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 nottableView.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