I am currently starting to learn how to build my own iOS Apps with Swift. My current project should help organize recipes. For this, the App displays a table with the some dishes (inside a Table View Controller at the start). Once the user clicks at a cell, the details of that dish (from my CoreDate) should be displayed inside a View Controller embedded inside a scroll view. So far so good... This is how my VieController for the clicked dish should look like:
Storyboard Image of my detail View
Inside this View Controller, I have a table with the ingredients needed for the dish. This table view should embed all the cells which describe the ingredients, as long as they together do not exceed a maximal height threshold of 300. In this case, all dishes are visible without scrolling. If a height of 300 is not enough to display all ingredients, the height of the table should be set to 300 and the user can scroll through the table of ingredients. So the height of the table depends on the size and content of the cells, which is why I can't just define it at the very start (at ViewDidLoad).
Now, when I click on the dish of my choice, the following screen appears:
Immediately after clicking dish
And after waiting maybe half a second, the view is updated appropriately:
So the problem is: the label "Zubereitung" right under my table only appears with a certain delay. I imagine that might be because the screen loads and initially works with the initial value I set my table height to be inside the storyboard(being 300). So the label "Zubereitung" stays 300 under the table. Only when I adjust the height of the table (in this case to a value below 300) can my label take its desired place.
That's why I wanted to ask, how I could avoid this problem. Or if there is a smarter or better way to adjust the table size dynamically with the content of my table? Currently I do it by overwriting the height constraint inside the function ViewDidAppear.
The code of the ViewController representing the selected dish is the following:
import UIKit
class MyDishViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var nameOfDish: UILabel!
@IBOutlet weak var imageOfDish: UIImageView!
@IBOutlet weak var categoryOfDish: UILabel!
@IBOutlet weak var complexityOfDish: UILabel!
@IBOutlet weak var time: UILabel!
@IBOutlet weak var ingredientTable: UITableView!
@IBOutlet weak var tableIngredientHeight: NSLayoutConstraint!
var dish : Dish? = nil
override func viewDidLoad() {
super.viewDidLoad()
ingredientTable.delegate = self
ingredientTable.dataSource = self
ingredientTable.rowHeight = UITableView.automaticDimension
ingredientTable.estimatedRowHeight = 60//0
if let text = dish?.nameDish{
nameOfDish.text = text
}
if let data = dish?.imageDish {
imageOfDish.image = UIImage(data: data)
}
if let category = dish?.category{
categoryOfDish.text = category
}
if let complexity = dish?.complexity{
complexityOfDish.text = complexity
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let height = self.ingredientTable.contentSize.height
if height > 300 {
self.tableIngredientHeight.constant = 300
}
else{
self.tableIngredientHeight.constant = height
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let ingredients = dish?.ingredients{
let lines = ingredients.split(whereSeparator: \.isNewline)
return lines.count
}
else{
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ingredientCell", for: indexPath) as! listingTableViewCell
if let ingredients = dish?.ingredients{
let lines = ingredients.split(whereSeparator: \.isNewline)
let item = lines[indexPath.row]
cell.item?.text = String(item)
}
return cell
}
}
Thank you very much!