Home > OS >  Is changing the table height by changing its contrains good practice?
Is changing the table height by changing its contrains good practice?

Time:09-17

I have a non-scrollable TableView. I want its height to be determined by the number of entries. To make this work I have used the height constraint (= CGFloat(data.count) * tableView.rowheight) of the TableView in the code. Is this good practice?

I noticed when I delete the last row of the TableView, it more or less skips the animation. Is this because the height of the table is adjusted faster than the animation needs? How can I solve this problem?


    var data = [1,2,3,4,5,6,7,8,9,10]

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var tableViewHeight: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.rowHeight = 50
        tableViewHeight.constant = CGFloat(data.count) * tableView.rowHeight
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = "\(data[indexPath.row])"
        return cell
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            data.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .automatic)
            self.tableViewHeight.constant = CGFloat(self.data.count) * self.tableView.rowHeight
        }
    }
    
    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(!isEditing, animated: true)
        tableView.setEditing(!tableView.isEditing, animated: true)
    }
}

CodePudding user response:

Things I look out for to avoid the problems you are in,

  • Try avoiding any constants or values for dimensions as much as possible.
  • Use constraints and try defining it in exactly one place ( StoryBoard, Xib, or in code).

As its height to be determined by its content attaching to screen edge won't work.

As for your queries,

  • Try checking if any conflicting constraints appear on the storyboard and code. Like if the whole tableview is defined in the storyboard, why not tableView.rowHeight = 50 remains there as well.
  • While deleting, tableView.deleteRows() have .autometic animation. As per doc, case automatic = 100 // available in iOS 5.0. chooses an appropriate animation style for you. Let's set that to .none.

Kindly check if the reviewed snippet below works.

   var data = [1,2,3,4,5,6,7,8,9,10]

    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var tableViewHeight: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.rowHeight = 50
        tableViewHeight.constant = CGFloat(data.count) * tableView.rowHeight
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        self.tableViewHeight.constant = CGFloat(self.data.count) * self.tableView.rowHeight
        return data.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = "\(data[indexPath.row])"
        return cell
    }
    
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        // I think this is causing the problem. 
         if editingStyle == .delete {
            data.remove(at: indexPath.row)
            // use no animation
            tableView.deleteRows(at: [indexPath], with: .none)
            // wont update the constraint here.
            // self.tableViewHeight.constant = CGFloat(self.data.count) * self.tableView.rowHeight
        }
    }
    
    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(!isEditing, animated: true)
        tableView.setEditing(!tableView.isEditing, animated: true)
    }
}

Also check these as well if haven't already,

CodePudding user response:

No, it's not.

Usually table view takes whole screen and should be attached to screen edges by constraints

UITableView is a subclass of UIScrollView which means that if content size is bigger than view size - it's gonna be easily scrolled

If by design it shouldn't take full screen, table view frame should be set to maximum expected size of many cells displayed

  • Related