设置tableViewContentSize为自身高度时,布局出错的解决办法

来源:互联网 发布:网页php的编程代码大全 编辑:程序博客网 时间:2024/06/05 04:49

项目中需求,tableView 需要被 add到一个scrollView上。tableView的内容完全平铺出来,即设置tableView的height等于tableView.ContentSize.height。 当数据刷新的时候,table的frame也需要动态改变,这时候有可能出现ui上的问题。

原因:当你reloadData后,contentsize有可能没有及时改变。这时候你设置的话就有可能出错。

方法1: 当tableView重新布局完成后,再设置frame。你可以在下一个runloop里设置frame。

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 *NSEC_PER_SEC)),dispatch_get_main_queue(), ^{

        CGFloat calendarMinHeight =self.s_CalendarView.m_MinHeight;

        CGSize remindTableViewContentSize =self.s_remindTableView.contentSize;

        CGFloat bottomPadding = [UIScreenmainScreen].bounds.size.height - 64 - calendarMinHeight - remindTableViewContentSize.height;

        bottomPadding = bottomPadding>=0 ? bottomPadding :0;

        // 根据tableview内容高度修改其frame高度约束

        self.s_RemindTableViewHeightConstraint.equalTo(@(remindTableViewContentSize.height));

        self.s_BottomPaddingViewHeightConstraint.equalTo(@(bottomPadding));

        

        [self.s_BackdropScrollViewupdateConstraintsIfNeeded];

        [self.s_BackdropScrollViewlayoutIfNeeded];

    });


此延时函数,可以 理解为将代码放到下一个runloop里运行。而这时tableView 已经重新布局完成。

这种方法的缺陷是,当数据多的时候,经测试,延时时间需要设置大一点,才能布局成功。

(tableVIew计算contentSize,你需要等他布局完成)。

方法2: 自己手动计算contentSize。即你拿到新的数据,需要reloadDate时。你自己根据数据计算高度并赋值。然后reloadData。这样不用等到下一个runloop。效果较好。

    NSInteger modelNum =0;

    for (int i =0; i <modelArray.count; i++)

    {

            modelNum += [modelArray[i]count];

    }

    CGRect frame =ScheduleTable.frame;

    frame.size.height = workListAry.count    * HistoryCellHeight;

    // 根据tableview内容高度修改其frame高度约束

    self.s_RemindTableViewHeightConstraint.equalTo(@(frame.size.height));

    self.s_BottomPaddingViewHeightConstraint.equalTo(@(bottomPadding));

    

    [self.s_BackdropScrollViewupdateConstraintsIfNeeded];

    [self.s_BackdropScrollViewlayoutIfNeeded];

    [ScheduleTablereloadData];




题外:另外一个场景很类似。我需要在界面显示的时候,将scrollVIew指定的contentoffSet展示出来。 我在ViewDidLoad里设置scrollView.contentoffSet = (0,200),没有效果。写在ViewDidAppear里有效果。因为ViewDidLoad 和VIewWillAppear在一个runloop里,这时还没有布局完成。而ViewDidAppear已经布局完成了。但是别的问题又来了,如果你写在ViewDidAppera里,你会看到界面闪一下。 我的临时做法是

在ViewDidload里,

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 *NSEC_PER_SEC)),dispatch_get_main_queue(), ^{


    CGFloat topInset =TimeScroll.contentInset.top;

    CGFloat beginOffsetY = -topInset;

    CGFloat calendarViewHiddenHeight = [self.s_CalendarViewintrinsicContentSize].height-self.s_CalendarView.m_MinHeight;

    CGFloat endOffsetY = beginOffsetY + calendarViewHiddenHeight;

    [self.s_BackdropScrollViewsetContentOffset:CGPointMake(0, endOffsetY) animated:NO];

    });

。这相当于在下一个runloop里设置了,那是已经布局完成了。不过建议尽量不用
阅读全文
0 0
原创粉丝点击