TableView关联导航控制器而非视图控制器导致数据显示位置异常
问题诊断
这个问题和控制器绑定逻辑无关,是代码错误导致的:
- 核心原因是TableView布局未适配安全区:你在
viewDidLayoutSubviews中直接将TableView的frame设置为view.bounds,导致视图从屏幕最顶部开始渲染,跑到了状态栏、导航栏的下层,也就是截图里黑圈标记的错误区域,没有自动对齐导航栏下方的正确内容区(红圈标记位置)。 - 代码里还存在两处会引发运行/编译异常的附带bug:一是
cellForRowAt方法中类型转换语法错误,as ? NewsTableViewCell中间多了空格,会直接导致编译失败;二是searchArticles接口回调中没有给articles数组赋值,同时两个异步接口同时触发会出现后返回的数据覆盖先返回数据的问题,点击cell时大概率触发数组越界。
修复步骤
1. 修正TableView布局,对齐正确内容区域
替换viewDidLayoutSubviews中的frame设置代码,适配系统安全区,TableView就会自动落在导航栏下方的正确位置:
override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() tableView.frame = view.safeAreaLayoutGuide.layoutFrame }
如果需要适配横竖屏切换、动态字体大小等场景,更推荐用Auto Layout替换手写frame,在viewDidLoad中view.addSubview(tableView)之后添加如下约束即可,适配性更强:
tableView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ])
2. 修复附带逻辑问题
- 修正类型转换语法:将
cellForRowAt中的as ? NewsTableViewCell改为as? NewsTableViewCell,移除as和?之间的空格。 - 补全数据赋值逻辑:在
searchArticles接口请求成功的回调中,和getTopArticles逻辑保持一致,先给articles数组赋值再生成viewModel,避免点击跳转时数组越界;如果页面初始加载不需要同时拉取头条和搜索结果,删掉其中一个接口调用即可,避免异步返回顺序不确定导致的数据错乱问题。
内容的提问来源于stack exchange,提问作者Shotty
相关产品推荐
相关产品推荐

