美文网首页
layoutIfNeeded使用-解决scrollToRowAt

layoutIfNeeded使用-解决scrollToRowAt

作者: 爱吃萝卜的小蘑菇 | 来源:发表于2020-04-15 16:36 被阅读0次

    最近开发遇到了两个问题,原因全是控件UI数据没有及时刷新导致的,最后的解决方案都是使用layoutIfNeeded解决。

    第一个问题

    [self.dataArray insertObjects:detailList atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, detailList.count)]];
    [self.mainTableView reloadData];
    [self.mainTableView layoutIfNeeded];
    if ([self.TRADESEQ isEqualToString:@""]) {
      [self.mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(detailList.count - 1) >= 0 ? (detailList.count - 1) : 0 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
    }else{
      [self.mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:detailList.count + 1 inSection:0] atScrollPosition:UITableViewScrollPositionNone animated:NO];
    }
    

    本来想调用scrollToRowAtIndexPath方法在请求完数据时,使TableView滚动到新数据的底部,但是第一次加载时显示正常,这个TableView定位到最底部,但是在加载更多时,会出现滚动位置错位的问题。这个需要在scrollToRowAtIndexPath方法前调用layoutIfNeeded
    原理:引用自https://www.cnblogs.com/LynnAIQ/p/5915117.html

    如果在reloadData后需要立即获取tableview的cell、高度,或者需要滚动tableview,那么,直接在reloadData后执行代码是有可能出问题的。
    reloadDate并不会等待tableview更新结束后才返回,而是立即返回,然后去计算表高度,获取cell等。
    如果表中的数据非常大,在一个run loop周期没执行完,这时,需要tableview视图数据的操作就会出问题了。
    apple并没有直接提供reloadData的api,想要程序延迟到reloadData结束在操作,可以用以下方法:

    方法一:
    [self.tableView reloadData];
    [self.tableView layoutIfNeeded];
    //刷新完成

    方法二:
    [self.tableView reloadData];
    dispatch_async(dispatch_get_main_queue(), ^{
    //刷新完成
    });
    reloadDate会在主队列执行,而dispatch_get_main_queue会等待机会,直到主队列空闲才执行。

    类似函数:

    • (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
    • (void)scrollToNearestSelectedRowAtScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;
    • (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated; // animate at constant velocity to new offset
    • (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated;

    当使用[tableView reloadData];刷新数据时,不能直接在后面使用上面的函数。reload

    第二个问题

    第二个问题简单描述就是xib加载的View在获取其中控件的frame是值不对,获取到的frame不是根据不同机型约束设置后显示出来的frame,而是在Xib中显示的原始大小。甚至在viewWillAppear方法中获取也是原始大小。
    解决方案也是在获取frame前调用layoutIfNeeded方法

    相关文章

      网友评论

          本文标题:layoutIfNeeded使用-解决scrollToRowAt

          本文链接:https://www.haomeiwen.com/subject/hmbcvhtx.html