layoutIfNeeded使用-解決scrollToRowAtIndexPath滾動(dòng)位置不對(duì),xib構(gòu)建的View獲取frame時(shí)不對(duì)

最近開發(fā)遇到了兩個(gè)問題,原因全是控件UI數(shù)據(jù)沒有及時(shí)刷新導(dǎo)致的,最后的解決方案都是使用layoutIfNeeded解決。

第一個(gè)問題

[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];
}

本來想調(diào)用scrollToRowAtIndexPath方法在請(qǐng)求完數(shù)據(jù)時(shí),使TableView滾動(dòng)到新數(shù)據(jù)的底部,但是第一次加載時(shí)顯示正常,這個(gè)TableView定位到最底部,但是在加載更多時(shí),會(huì)出現(xiàn)滾動(dòng)位置錯(cuò)位的問題。這個(gè)需要在scrollToRowAtIndexPath方法前調(diào)用layoutIfNeeded
原理:引用自https://www.cnblogs.com/LynnAIQ/p/5915117.html

如果在reloadData后需要立即獲取tableview的cell、高度,或者需要滾動(dòng)tableview,那么,直接在reloadData后執(zhí)行代碼是有可能出問題的。
reloadDate并不會(huì)等待tableview更新結(jié)束后才返回,而是立即返回,然后去計(jì)算表高度,獲取cell等。
如果表中的數(shù)據(jù)非常大,在一個(gè)run loop周期沒執(zhí)行完,這時(shí),需要tableview視圖數(shù)據(jù)的操作就會(huì)出問題了。
apple并沒有直接提供reloadData的api,想要程序延遲到reloadData結(jié)束在操作,可以用以下方法:

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

方法二:
[self.tableView reloadData];
dispatch_async(dispatch_get_main_queue(), ^{
//刷新完成
});
reloadDate會(huì)在主隊(duì)列執(zhí)行,而dispatch_get_main_queue會(huì)等待機(jī)會(huì),直到主隊(duì)列空閑才執(zhí)行。

類似函數(shù):

  • (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;

當(dāng)使用[tableView reloadData];刷新數(shù)據(jù)時(shí),不能直接在后面使用上面的函數(shù)。reload

第二個(gè)問題

第二個(gè)問題簡(jiǎn)單描述就是xib加載的View在獲取其中控件的frame是值不對(duì),獲取到的frame不是根據(jù)不同機(jī)型約束設(shè)置后顯示出來的frame,而是在Xib中顯示的原始大小。甚至在viewWillAppear方法中獲取也是原始大小。
解決方案也是在獲取frame前調(diào)用layoutIfNeeded方法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容