设备旋转后UITableView无法自适应屏幕的问题求助
嘿,我帮你梳理下问题所在,其实核心是你的Auto Layout约束写错了,导致旋转后tableView没有正确铺满屏幕。咱们一步步来修复:
首先看你代码里的关键错误
你在设置trailing约束的时候犯了一个低级错误:
tableView.trailingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
这里把layoutGuide.trailingAnchor写成了leadingAnchor,相当于让tableView的右边对齐安全区域的左边,直接导致tableView的宽度异常,旋转后自然会露出背后的屏幕,这是最主要的问题。
另外,你同时使用了Auto Layout约束和手动设置frame:
tableView.frame = self.view.bounds
当你给视图添加Auto Layout约束后,系统会自动接管视图的frame计算,手动设置的frame会被Auto Layout覆盖,这行代码完全多余,甚至可能引发布局冲突。
还有你之前尝试的UIViewAutoresizingFlexibleHeight报错,是因为Swift里这个枚举的写法已经更新了,正确写法是UIView.AutoresizingMask.flexibleHeight,不过既然你用了Auto Layout约束,其实不需要设置autoresizingMask,约束已经能处理横竖屏适配了。
修正后的完整代码
把这些问题修复后,你的viewDidLoad代码应该是这样的:
super.viewDidLoad() // 初始化tableView,用view.bounds作为初始frame没问题 tableView = UITableView(frame: view.bounds, style: .plain) tableView.backgroundColor = UIColor.blue // 注册cell let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil) tableView.register(cellNib, forCellReuseIdentifier: "postCell") tableView.register(LoadingCell.self, forCellReuseIdentifier: "loadingCell") // 添加到父视图 view.addSubview(tableView) // 设置Auto Layout约束 let layoutGuide = view.safeAreaLayoutGuide // 确保关闭自动转换autoresizingMask为约束的功能(iOS9+用anchor约束会自动设,但手动加上更稳妥) tableView.translatesAutoresizingMaskIntoConstraints = false // 修正trailing约束,用数组批量激活约束更简洁 NSLayoutConstraint.activate([ tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor), tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor), tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor) ]) // 其他tableView设置 tableView.estimatedRowHeight = UITableView.automaticDimension tableView.delegate = self tableView.dataSource = self tableView.tableFooterView = UIView() tableView.reloadData()
为什么之前的didRotate方法没用?
因为你的约束本身就有错误,旋转后Auto Layout会根据错误的约束计算frame,所以即使你在didRotate里重新设置frame,也会被Auto Layout的约束覆盖,根本起不到作用。修复约束后,Auto Layout会自动在旋转时更新tableView的frame,不需要额外处理旋转事件。
这样修改后,无论是启动时的横竖屏,还是旋转后的屏幕,tableView都能正确铺满安全区域了。
内容的提问来源于stack exchange,提问作者EverythingEnds

