首先说明,我的这个问题不具有普遍性,是一个偶然才会发生的事件。
通常情况下,我们只需要把tableview的header和footer设置成0.01的高度就不会有问题了。如下图:
image.png
但是今天说的这种问题,却是不受tableview的header和footer的影响的。
问题描述:
1.tableview的type为grouped;
2.使用了viewModel,且viewModel是懒加载的;
3.使用多线程进行reloadData,且多线程中才第一次调用viewModel。
问题截图:
image.png image.png
来看代码吧:
ViewController:
//
// ViewController.swift
// Test
//
// Created by iOS on 2018/12/29.
// Copyright © 2018 weiman. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
private lazy var viewModel = ViewModel(newTableView)
// private var viewModel: ViewModel?
private lazy var newTableView: UITableView = {
return $0
}( UITableView(frame: .zero, style: .grouped) )
override func viewDidLoad() {
super.viewDidLoad()
automaticallyAdjustsScrollViewInsets = false
// setup()
loadData()
}
private func setup() {
// let _ = viewModel
// viewModel = ViewModel(tableView)
let frame = CGRect(x: 0,
y: 100,
width: view.frame.size.width,
height: view.frame.size.height - 100 - 49)
newTableView.frame = frame
newTableView.backgroundColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
}
}
extension ViewController {
private func loadData() {
// let group = DispatchGroup()
//
// group.enter()
// let work1 = DispatchQueue(label: "1")
// work1.async {
// print("线程1")
// Thread.sleep(forTimeInterval: 2)
// print("线程1执行完成")
// group.leave()
// }
//
// group.enter()
// let work2 = DispatchQueue(label: "2")
// work2.async {
// print("线程2")
// Thread.sleep(forTimeInterval: 3)
// print("线程2执行完成")
// group.leave()
// }
//
// group.notify(queue: .main) { [weak self] in
// guard let self = self else { return }
// let _ = self.viewModel
// DispatchQueue.main.asyncAfter(deadline: .now() + 5.0, execute: {
// print("reload")
// self.viewModel.reload()
// })
// }
// self.viewModel.reload()
/*
while(!isFinished) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; }
*/
// viewModel.tableView.delegate = viewModel
// viewModel.tableView.dataSource = viewModel
DispatchQueue.main.asyncAfter(deadline: .now()) {
self.setup()
self.view.addSubview(self.newTableView)
self.newTableView.delegate = self.viewModel
self.newTableView.dataSource = self.viewModel
self.viewModel.reload()
}
}
}
ViewModel
//
// ViewModel.swift
// Test
//
// Created by iOS on 2018/12/29.
// Copyright © 2018 weiman. All rights reserved.
//
import UIKit
class ViewModel: NSObject {
let tableView: UITableView
init(_ tableView: UITableView) {
self.tableView = tableView
super.init()
setup()
}
private func setup() {
// tableView.delegate = self
// tableView.dataSource = self
tableView.estimatedRowHeight = 0
tableView.estimatedSectionFooterHeight = 0
tableView.estimatedSectionHeaderHeight = 0
if #available(iOS 11.0, *) {
tableView.contentInsetAdjustmentBehavior = .never
}
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.register(Header.self, forHeaderFooterViewReuseIdentifier: "header")
tableView.register(Footer.self, forHeaderFooterViewReuseIdentifier: "footer")
}
func reload() {
tableView.reloadData()
}
}
extension ViewModel: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0: return 1
case 1: return 3
case 2: return 1
default: return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "哈哈哈哈"
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header")
header?.contentView.backgroundColor = #colorLiteral(red: 0.4745098054, green: 0.8392156959, blue: 0.9764705896, alpha: 1)
return header
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: "footer")
footer?.contentView.backgroundColor = #colorLiteral(red: 0.8549019694, green: 0.250980407, blue: 0.4784313738, alpha: 1)
return footer
}
}
extension ViewModel: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
print("heightForHeaderInSection: \(section)")
switch section {
case 1, 2: return 60
default: return 0.01
}
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
print("heightForFooterInSection: \(section)")
return 0.01
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(tableView.contentOffset)
}
}
把代码修改成如下这样都是没有问题的:
方法一:把self.view.addSubview(self.newTableView)放在设置代理的后面。
image.png
方法二:去掉多线程
image.png方法三:把设置代理的方法放在外面
image.png方法四: 不使用懒加载;
方法五:在viewdidload中,先把懒加载给初始化;
实在想不明白为什么,还请大神出来解释一下呗,感激不尽。
demo地址:https://github.com/weiman152/TableViewGroupedTest/tree/master
网友评论