UITableView滚动响应异常求助:时而正常时而完全无法滚动
看起来你遇到了纯代码实现的booktable滚动不稳定的问题,结合你的代码片段,我整理了几个最可能的原因和对应的修复方案:
1. 优先检查TableView的frame计算时机
你当前在初始化时直接计算booktable的frame,但如果这段代码是在viewDidLoad里执行的,此时booktopview和tabbarView的布局还没完全完成,它们的bounds.height可能不是最终的真实值,导致booktable的高度或位置计算错误——比如高度被算成0,或者被其他视图遮挡,自然会出现滚动异常。
修复方案:把frame设置的代码移到viewDidLayoutSubviews方法中,这个方法会在视图布局全部完成后调用,能拿到准确的视图尺寸:
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // 重新计算tableView的frame let tableY = booktopview.bounds.height let tableWidth = UIScreen.main.bounds.width let tableHeight = UIScreen.main.bounds.height - tableY - tabbarView.bounds.height booktable.frame = CGRect(x: 0, y: tableY, width: tableWidth, height: tableHeight) }
2. 必须明确指定TableView的行高
你的代码里没有实现tableView(_:heightForRowAt:)方法,UITableView默认会尝试自动估算行高,但手动布局cell的情况下,自动估算很容易出错,导致contentSize计算异常,直接影响滚动行为。
修复方案:添加行高代理方法,根据你手动设置的cell子视图尺寸,返回准确的行高(比如你的图片高度是130,上下各15间距,行高应该是160):
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { guard tableView == booktable else { return UITableView.automaticDimension } // 根据你的cell布局,返回固定行高 return 160 }
如果需要动态行高,也可以先设置估算高度,再让系统自动计算:
// 在初始化booktable时添加 booktable.estimatedRowHeight = 160 booktable.rowHeight = UITableView.automaticDimension
但手动布局cell时,固定行高的稳定性更高。
3. 检查是否有视图遮挡或触摸事件被拦截
有时候滚动失效是因为booktable被其他视图(比如booktopview或tabbarView)超出自身frame的部分覆盖了,导致触摸事件无法传递到tableView上。
排查方法:临时给booktable设置一个显眼的背景色(比如booktable.backgroundColor = .red),运行后观察tableView的实际显示区域是否完整,有没有被其他视图挡住。同时确认booktable.isUserInteractionEnabled是true(默认是true,但如果不小心被修改过就会失效)。
4. 优化cell复用的子视图移除逻辑
你当前在复用cell时直接移除所有子视图:
for object in (cell1?.contentView.subviews)! { object.removeFromSuperview(); }
这种写法用了强制解包!,存在崩溃风险,而且可能误删UITableViewCell的系统默认视图(虽然概率低,但会埋下隐患)。建议通过tag来精准移除自己添加的子视图:
// 添加子视图时设置tag img.tag = 100 lbl.tag = 101 // 复用cell时只移除自己添加的视图 if let oldImg = cell1?.contentView.viewWithTag(100) { oldImg.removeFromSuperview() } if let oldLbl = cell1?.contentView.viewWithTag(101) { oldLbl.removeFromSuperview() }
5. 确认屏幕尺寸的获取是否正确
确保你用的screenWidth和screenHeight是当前屏幕的真实尺寸,建议直接使用UIScreen.main.bounds来获取,避免自定义变量出错:
let screenWidth = UIScreen.main.bounds.width let screenHeight = UIScreen.main.bounds.height
先从第一和第二个方案开始排查,这两个是UITableView滚动异常最常见的原因,大概率能解决你的问题。
内容的提问来源于stack exchange,提问作者vishnu

