如何为动态调整高度的UITableView设置高度上限?
Hey there! Let's get your table view to dynamically adjust its height based on content while respecting a maximum height cap. Your current approach uses frame manipulation, which can be inconsistent with Auto Layout—let's switch to using your existing tableViewHeightConstraint properly, since you already have it set up.
Step 1: Define Your Maximum Height
First, add a constant at the top of your view controller to set the upper limit (adjust this value to fit your needs):
let maxTableViewHeight: CGFloat = 200 // Change this to your desired max height
Step 2: Create a Reusable Height Update Method
Instead of repeating frame code in multiple places, make a single method to calculate and set the table view's height correctly:
private func updateTableViewHeight() { // Calculate the required height based on content let requiredHeight = tableView.contentSize.height // Use the smaller value between required height and max height let constrainedHeight = min(requiredHeight, maxTableViewHeight) // Update the constraint instead of modifying the frame directly tableViewHeightConstraint.constant = constrainedHeight // Force layout update to apply changes immediately view.layoutIfNeeded() }
Step 3: Replace Frame Manipulation with the New Method
Update your viewWillAppear and viewDidLayoutSubviews methods to use this method instead of modifying the frame:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Don't forget to call super! updateTableViewHeight() // Add a border to the tableView tableView.layer.borderWidth = 1 tableView.layer.borderColor = UIColor.black.cgColor print("We ran ViewWillAppear") } override func viewDidLayoutSubviews(){ super.viewDidLayoutSubviews() // Always call super here updateTableViewHeight() // No need to reloadData here unless you have dynamic content changes triggering layout }
Step 4: Fix the Delete Action
Your current delete action manually subtracts 44 from the height, which is fragile (what if your row height changes later?). Instead, call our reusable method after deleting the row:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { let delete = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in // Delete item at indexPath self.items.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .fade) // Let our method handle the height update self.updateTableViewHeight() print(self.items) print("Number of rows: \(tableView.numberOfRows(inSection: 0))") } delete.backgroundColor = UIColor.blue return [delete] }
Step 5: Ensure Proper Row Height Setup (Optional but Recommended)
If you ever use custom cell heights, make sure your table view is configured to calculate row heights correctly:
override func viewDidLoad() { super.viewDidLoad() // Set automatic row height if needed (skip if using fixed row height) tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 44 // Estimate for smooth layout }
Why This Works
- By using Auto Layout constraints instead of direct frame changes, we play nice with iOS's layout system, avoiding unexpected behavior during rotations or screen size changes.
- The
min(requiredHeight, maxTableViewHeight)ensures the table view never grows beyond your specified limit, while still shrinking when content is removed. - The reusable method keeps your code clean and easy to maintain—you only need to adjust the max height in one place.
内容的提问来源于stack exchange,提问作者Everett

