Today I have gone through with the very varied behaviour of the table view. It's bounce every time I call reload function as my table view cells are dynamic and having a different type of contents, so I used the property of UITableViewAutomaticDimension for row height.
So, to resolve this bounce issue on the reload function of the table. I have to store the height of the row from tableView willDisplay cell method and used the same in estimatedHeightForRowAt. Please find the code below. Hope it will help someone.
var height_OfCells = NSMutableDictionary()
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if let height = height_OfCells.object(forKey: indexPath) {
return height as! CGFloat
}
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
height_OfCells.setObject(cell.frame.size.height, forKey: indexPath as NSCopying)
}
Related
Here table view cell height was expanded but the label content view was not properly displayed but button action triggered in the bottom position of the view can anyone help me to sort out this?
The code used is
self.cancelOrderTableView.estimatedRowHeight = 44.0
self.cancelOrderTableView.rowHeight = UITableView.automaticDimension
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 300
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
My tableview cell won't show correctly. I have no idea what the problem is. When I launch the simulator it will show this: Simulator. I have used Contraints and I know for sure that the Contraints are correct. This is how it needs to be: How it must look like. Please help!
Add these in your code
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 80.0
}
If you have multiple heights then put condition like this
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if(indexPath.section == 0){
return 50
}else{
retrn 120
}
}
Or use automatic dimension, with resizes every cell automatically according to its content:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
I have a UILabel in UITableViewCell.I have given it's constraints as Top,Bottom,Leading ,Trailing. If I give it numberoflines as 0 then it does not take any space.But if give it fix number of lines then it takes extra space from top & bottom. Please tell me what is the issue ?
Code for UITableView Delegates
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Constraints Given as
Screenshot for the UITableViewCell
When you give number of lines 0 along with the above constraints, the UILabel will have auto height, which means the AutomaticDimension for tableview cell will height relative to UILabel. When UILabel's text is empty, it's height becomes zero.
To overcome this situation, you can specify either of two things:
Minimum height for the UILabel (e.g. in the constraint give height > 30)
Estimated height for UITableViewCell using delegate method
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let lbl = cell.contentView.viewWithTag(10) as! UILabel
lbl.text = "abcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksdabcljfdslkfj;dlskfjd;slkfjds;ljdsfldjsf;ldsjfdslkfjds;lfjds;lfjdfl;jdsf;lkdjsf;ldsjf;ldskjd;slfjdsl;fjd;fljdfl;kjsdflljksd"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
}
I'm trying to implement infinite scrolling in UITableView by checking the indexpath at "willDisplay cell", however once the table is loaded with data, the "willDisplay cell" func seems to be drawing all cells before I scroll down although the mobile screen can only fit one or two cells at a time.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
print(indexPath.row)
}
Output without scrolling down:
0
1
2
3
4
5
When I scroll down the "willDisplay cell" func works properly and it prints the indexpath.row one at a time.
What could be the problem here?
Here's a look at the full code:
override func viewDidLoad() {
super.viewDidLoad()
postsTableview.delegate = self
postsTableview.dataSource = self
let nibName = UINib(nibName: "postTableViewCell", bundle:nil)
postsTableview.register(nibName, forCellReuseIdentifier: "postTableViewCell")
loadPosts()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postTableViewCell", for: indexPath) as! postTableViewCell
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
print(indexPath.row)
}
I have tried setting the tableview cell height fixed with large value that exceeds the screen height but I still have the same problem
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
return 1000.0;
}
It turned out that I needed to set an estimated row height. I'm coming from Android background and this sounds silly to me but it worked out.
postsTableview.estimatedRowHeight = 400
postsTableview.rowHeight = UITableViewAutomaticDimension
On your edited question:
There's nothing wrong with iOS, all table/collection view cells are drawn before they are shown; imagine a table view that shows nothing in the beginning when it's shown, would that be weird?
I don't know what you are trying to achieve after the cells are shown, but I believe that's suitable for another question, good luck!
I am trying to set the row height dynamically based on the content set in the detail text label, by using the below code in Part A.
I am inserting few lines of text into a cell's detail text label as shown below in Part B
I've looked at other similar questions but none have helped.
Can some one please advice how I can adjust the row height dynamically based on the content of the detail text label.
Part A
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Also tried
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Part B
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "daysIdentifier", for: indexPath)
cell.textLabel?.text = days[indexPath.row]
cell.detailTextLabel?.numberOfLines = 0
var joinedString = self.availabilityTimeDict[dayName]?.joined(separator: " \n ")
cell.detailTextLabel?.text = joinedString
return cell
}
Use custom cell and labels.
Set up the constrains for the UILabel. (top, left, bottom, right)
Set lines of the UILabel to 0
Add the following code in the viewDidLoad method of the ViewController:
tableView.estimatedRowHeight = 68.0
tableView.rowHeight = UITableView.automaticDimension
// Delegate & data source
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableView.automaticDimension;
}
Swift 4:
// Delegate & data source
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Swift 4.2:
// Delegate & data source
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
give top,bottom,leading and trailing to your lable inside content of tableview.Use below methods of table view
func tableView(_ tableView: UITableView,heightForRowAt indexPath:IndexPath) -> CGFloat
{
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
{
return 100
}
First setup a custom cell and add a label and set its number of lines to zero and give bottom, top, leading, trailing constraints to cell's content view(dont give the height) also give a custom height to cell in size inspector then in viewDidLoad you just need to do,
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 100.0