Home > OS >  Weird behaviour of UITableViewCell after table reload when paging enabled for UITableView
Weird behaviour of UITableViewCell after table reload when paging enabled for UITableView

Time:09-17

I have an UITableView and inside UITableViewCell, I have added view and trying to set the height of that view or height of the cell according to screen height or UITableView's height. Initially, I was able to do it but when in the viewWillAppear reloading table, not able to set the proper height for that view or height of the cell. It's the height or some other problem, not able to identify. Any help would be appreciated and Thanks for the reply. The title of the question may be confusing or do you find any unrelated code then suggestions(edits) are welcome.

Code:

import UIKit

class PageViewController: UIViewController {
    @IBOutlet weak var tblPager: UITableView!
    let screenHeight = UIScreen.main.bounds.size.height
    
    let vColors: [UIColor] = [.red, .blue, .orange, .brown, .cyan, .darkGray, .green, .red, .blue, .orange, .brown, .cyan, .darkGray, .green]

    var pageSizeHeight: CGFloat = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        pageSizeHeight = screenHeight - (getTopSafeArea()   getBottomSafeArea()   54)
    }
   
    override func viewWillAppear(_ animated: Bool) {
        
        super.viewWillAppear(animated)
        
        delay(interval: 10.0) {
            
            print("Reload table after 10 seconds")
            self.tblPager.reloadData()
        }
    }
    
}

//MARK:- TableView Delegate
extension PageViewController: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return vColors.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "PageCell", for: indexPath) as! PageCell
        cell.backgroundColor = vColors[indexPath.row]
        
        cell.viewHeight.constant = pageSizeHeight
        return cell
    }
    
}

class PageCell: UITableViewCell {
    @IBOutlet weak var vwPage: UIView!
    @IBOutlet weak var viewHeight: NSLayoutConstraint!
}

func getTopSafeArea() -> CGFloat {
    let window = UIApplication.shared.keyWindow
    let topPadding = window?.safeAreaInsets.top ?? 0
    return topPadding
}

func getBottomSafeArea() -> CGFloat {
    let window = UIApplication.shared.keyWindow
    let bottomPadding = window?.safeAreaInsets.bottom ?? 0
    return bottomPadding
}

func delay(interval: TimeInterval, closure: @escaping () -> Void) {
    DispatchQueue.main.asyncAfter(deadline: .now()   interval) {
        closure()
    }
}

enter image description here

Output:

enter image description here

CodePudding user response:

if all cells will have the same height, why don't you set the rowHeight property inside viewWillLayoutSubviews method?

 override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        tblPager.rowHeight = tblPager.frame.height
    }

Thanks to @Desdenova for correcting me


By setting dataSource and delegate of tblPager to self in PageViewController's viewDidLoad and setting the rowHeight property in viewDidLayoutSubviews, tableView behaves as expected.

 override func viewDidLoad() {
        super.viewDidLoad()
        tblPager.register(UINib(nibName: "PageTableViewCell", bundle: nil), forCellReuseIdentifier: "PageCell")
        tblPager.dataSource = self
        tblPager.delegate = self
    }
    
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        tblPager.rowHeight = tblPager.frame.size.height
    }

enter image description here

CodePudding user response:

Link it to tableView's height, your table view has all sizes you need.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) {
   // ...
   cell.viewHeight.constant = tableView.frame.size.heigh
   // ...
}

or remove viewHeight constraint and use delegate method to set row height

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
   return tableView.frame.size.height
}

UPD:

TableView using estimatedRowHeight to calculate its scroll offsets. This does create an issue during reload if we have enabled paging and do not configure estimatedRowHeight.

Solution 1: Implement estimatedHeightForRowAt delegate

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
     return tableView.frame.size.height
}

Solution 2: Set tableView.estimatedRowHeight = 0 and use heightForRowAt delegate instead of viewHeight constraint

  • Related