iOS:UITabBarController下RefreshControl搭配large title工作异常
问题原因
这是iOS系统嵌套UITabBarController+开启大标题模式下的已知布局Bug:纯代码布局时,系统对UITableView的初始contentOffset和adjustedContentInset计算顺序出错,导致UIRefreshControl初始位置就处于触发阈值的临界点,轻微滚动就会触发valueChanged事件。Storyboard布局时系统会自动处理初始布局偏移,因此不会出现该问题。
修复方案
可选择以下任意一种方案修复,均不影响「内容从NavigationBar下方穿过」的透明毛玻璃效果:
方案1:修正初始偏移(最推荐,无副作用)
在你的ViewController中添加以下代码,首次布局时修正tableView的初始偏移量:
class ViewController: UIViewController { // 新增标记变量 private var isFirstLayout = true // 重写安全区域变更方法 override func viewSafeAreaInsetsDidChange() { super.viewSafeAreaInsetsDidChange() guard isFirstLayout else { return } isFirstLayout = false // 修正初始偏移,匹配large title状态下的正确偏移 tableView.contentOffset = CGPoint(x: 0, y: -tableView.adjustedContentInset.top) } // 原有代码保持不变 }
方案2:调整内容缩进适配规则
如果业务允许修改tableView的缩进适配行为,也可以在viewDidLoad中添加以下代码:
override func viewDidLoad() { super.viewDidLoad() // 新增代码 if #available(iOS 11.0, *) { tableView.contentInsetAdjustmentBehavior = .scrollableAxes } else { automaticallyAdjustsScrollViewInsets = false } // 原有代码保持不变 }
方案3:推迟refreshControl赋值时机
也可以把refreshControl的赋值操作从viewDidLoad推迟到首次页面展示之后:
// 先删除viewDidLoad里的 tableView.refreshControl = refreshControl 代码 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) tableView.refreshControl = refreshControl }
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

