如何动态设置tableView的高度?
How to dynamically set tableView height?
我很难根据它的内容设置我的 tableView
高度。我的单元格具有动态高度,如果我为我的 table 视图硬编码高度,我可以看到它们很好。现在我的问题是:
我的 table 视图没有根据我的单元格调整到正确的高度
如果我没有为 table 视图设置静态高度,则不会渲染单元格
红利问题:我使用 SnapKit 进行约束,当我根据内容大小重新制作约束以适应我的 table 视图高度时,它会触发 viewDidLoad
和我的细胞数一样多*
这里说的都是一些代码:
class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
private var cellHeight: CGFloat? = UITableView.automaticDimension
private var hasLoader: Bool = true
lazy var tableView: UITableView! = UITableView()
lazy var loadMoreButton: UIButton! = PrimaryButton(textKey: "actionSeeMore")
lazy var emptyView: UILabel! = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(Cell.self, forCellReuseIdentifier: "Cell")
tableView.dataSource = self
tableView.delegate = self
tableView.separatorStyle = .none
tableView.rowHeight = UITableView.automaticDimension
initActions()
initLayout()
}
override func viewWillAppear(_ animated: Bool) {
loadList(appendItems: true)
}
func initLayout() {
self.view.addSubview(tableView)
self.view.addSubview(emptyView)
self.view.addSubview(loadMoreButton)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.snp.makeConstraints { (make) -> Void in
make.left.right.leading.trailing.top.equalToSuperview()
if(self.hasLoader == true) {
make.bottom.equalTo(self.loadMoreButton.snp.top).offset(-15)
}
print("PRINT TABLE HEIGHT", self.tableView.contentSize.height) // It's 0.0
make.height.equalTo(1000) // Just trying things
}
tableView.isScrollEnabled = false
emptyView.translatesAutoresizingMaskIntoConstraints = false
emptyView.isHidden = true
emptyView.textAlignment = .center
emptyView.snp.makeConstraints { (make) -> Void in
make.left.right.leading.trailing.equalToSuperview()
make.top.equalToSuperview().offset(8)
}
self.loadMoreButton.isHidden = true
if(self.hasLoader == true) {
self.loadMoreButton.isHidden = false
loadMoreButton.translatesAutoresizingMaskIntoConstraints = false
loadMoreButton.snp.makeConstraints { (make) -> Void in
make.centerX.equalToSuperview()
make.top.equalTo(tableView.snp.bottom)
}
}
}
func initActions() {
loadMoreButton.addTarget(self, action: #selector(self.loadMoreOnClick(sender:)), for: .touchUpInside)
}
func loadList(appendItems: Bool) {
DispatchQueue.main.async {
self.apiClient.getList(completion: { _ in
DispatchQueue.main.async {
self.tableView.reloadData()
// Here I normally do tableView.snp.remakeConstraints { (make) in make.height.equalTo(self.tableView.contentSize.height) } which fires viewDidLoad many times (as much as I have cells)
}
})
}
}
func loadMore() {
self.page += 1
self.loadList(appendItems: true)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return resourceList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! Cell
let currentResource = resourceList[indexPath.row]
cell.setResource(resource: currentResource)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.tableView.deselectRow(at: indexPath, animated: true)
let resource = resourceList[indexPath.row]
if (resource.getRouteParam() != "") {
router.setRoute(routeName: resource.getRouteName(), routeParam:
resource.getRouteParam())
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
为了便于阅读,我省略了部分代码。
尝试以下操作:
- 像这样在
UIViewController
子类中声明一个变量。
private var contentSizeObservation: NSKeyValueObservation?
- 在
viewDidLoad()
内或设置 myTableView
时,开始观察 contentSize 的变化。
contentSizeObservation = myTableView.observe(\.contentSize, options: .new, changeHandler: { [weak self] (tv, _) in
guard let self = self else { return }
self.myTableViewHeightConstraint.constant = tv.contentSize.height
})
- 不要忘记在
deinit
调用 - 中清理它
deinit {
contentSizeObservation?.invalidate()
}
这种方法将确保您的 myTableView
的高度始终与其内容一样大。
我很难根据它的内容设置我的 tableView
高度。我的单元格具有动态高度,如果我为我的 table 视图硬编码高度,我可以看到它们很好。现在我的问题是:
我的 table 视图没有根据我的单元格调整到正确的高度
如果我没有为 table 视图设置静态高度,则不会渲染单元格
红利问题:我使用 SnapKit 进行约束,当我根据内容大小重新制作约束以适应我的 table 视图高度时,它会触发
viewDidLoad
和我的细胞数一样多*
这里说的都是一些代码:
class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
private var cellHeight: CGFloat? = UITableView.automaticDimension
private var hasLoader: Bool = true
lazy var tableView: UITableView! = UITableView()
lazy var loadMoreButton: UIButton! = PrimaryButton(textKey: "actionSeeMore")
lazy var emptyView: UILabel! = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(Cell.self, forCellReuseIdentifier: "Cell")
tableView.dataSource = self
tableView.delegate = self
tableView.separatorStyle = .none
tableView.rowHeight = UITableView.automaticDimension
initActions()
initLayout()
}
override func viewWillAppear(_ animated: Bool) {
loadList(appendItems: true)
}
func initLayout() {
self.view.addSubview(tableView)
self.view.addSubview(emptyView)
self.view.addSubview(loadMoreButton)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.snp.makeConstraints { (make) -> Void in
make.left.right.leading.trailing.top.equalToSuperview()
if(self.hasLoader == true) {
make.bottom.equalTo(self.loadMoreButton.snp.top).offset(-15)
}
print("PRINT TABLE HEIGHT", self.tableView.contentSize.height) // It's 0.0
make.height.equalTo(1000) // Just trying things
}
tableView.isScrollEnabled = false
emptyView.translatesAutoresizingMaskIntoConstraints = false
emptyView.isHidden = true
emptyView.textAlignment = .center
emptyView.snp.makeConstraints { (make) -> Void in
make.left.right.leading.trailing.equalToSuperview()
make.top.equalToSuperview().offset(8)
}
self.loadMoreButton.isHidden = true
if(self.hasLoader == true) {
self.loadMoreButton.isHidden = false
loadMoreButton.translatesAutoresizingMaskIntoConstraints = false
loadMoreButton.snp.makeConstraints { (make) -> Void in
make.centerX.equalToSuperview()
make.top.equalTo(tableView.snp.bottom)
}
}
}
func initActions() {
loadMoreButton.addTarget(self, action: #selector(self.loadMoreOnClick(sender:)), for: .touchUpInside)
}
func loadList(appendItems: Bool) {
DispatchQueue.main.async {
self.apiClient.getList(completion: { _ in
DispatchQueue.main.async {
self.tableView.reloadData()
// Here I normally do tableView.snp.remakeConstraints { (make) in make.height.equalTo(self.tableView.contentSize.height) } which fires viewDidLoad many times (as much as I have cells)
}
})
}
}
func loadMore() {
self.page += 1
self.loadList(appendItems: true)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return resourceList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! Cell
let currentResource = resourceList[indexPath.row]
cell.setResource(resource: currentResource)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.tableView.deselectRow(at: indexPath, animated: true)
let resource = resourceList[indexPath.row]
if (resource.getRouteParam() != "") {
router.setRoute(routeName: resource.getRouteName(), routeParam:
resource.getRouteParam())
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
为了便于阅读,我省略了部分代码。
尝试以下操作:
- 像这样在
UIViewController
子类中声明一个变量。
private var contentSizeObservation: NSKeyValueObservation?
- 在
viewDidLoad()
内或设置myTableView
时,开始观察 contentSize 的变化。
contentSizeObservation = myTableView.observe(\.contentSize, options: .new, changeHandler: { [weak self] (tv, _) in
guard let self = self else { return }
self.myTableViewHeightConstraint.constant = tv.contentSize.height
})
- 不要忘记在
deinit
调用 - 中清理它
deinit {
contentSizeObservation?.invalidate()
}
这种方法将确保您的 myTableView
的高度始终与其内容一样大。