I have multiple tableviews in my ViewController and each tableview has different number of rows, please see image below:
Is there any way to match the height of the tableview according to its number of rows?
In your view controller, put code similar to the following:
override func updateViewConstraints() {
super.updateViewConstraints()
tableViewHeightConstraint.constant = tableView.contentSize.height;
}
Where tableViewHeightConstraint is an #IBOutlet to NSLayoutConstraint. Obviously with multiple table views you will need to reference multiple height constraints, so you'd just have one line in updateViewConstraints for each table view you want.
The advantage of this technique is that it takes all of the table view's content into account. It handles grouping, automatic cell height, etc.
You have to determine how many cells you have, then override
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return CGRectGetHeight(self.tableView.bounds) / self.tableView.numberOfRowsInSection(indexPath.section)
}
Btw, I suppose making use of header cells would be a better idea than implementing multiple tableviews.
Related
I have a design, where UITableView is in UIScrollView with other content and the content is scrolling with the table data. It means, that table has scrolling disabled and is stretched to full size.
I'm using autolayout and the table has height constraint, set to some default value.
Then I have overwritten viewWillLayoutSubviews method:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if (self.itemTableView.contentSize.height > 0) {
self.itemTableViewHeightConstraint.constant = self.itemTableView.contentSize.height
}
}
With this method in place, when I called self.itemTableView.reloadData() after loading the data from the REST, the height constraint was set to table content height, which was great.
This used to work for me in many projects, but for some reason it is not working in the latest one, written in swift 4. Does something changed? Why tableView reloadData() method does not invoke viewWillLayoutSubviews()?
The problem was that the tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) was not calling self.view.setNeedsLayout() before returning row.
I have UITableView in UIViewController in this view controller total 3 tableview or 2 UICollectionView. so in this one tableview contain many cells or cells data are not static its dynamic according to server. So, I create the table view height outlet & its set on cellforrowatindex function of tableview.
So, we use to set height tableview_height.constant=tableview_height.constant+cell.frame.size.height using this code my problem showing whitespace on the end of UITableViewCell. If I increase the cell then cell are cut from the bottom. I am giving below constraint show in the pic.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if indexPath.row == 0
{
tableview_height.constant = 0
tableview_height.constant=tableview_height.constant+cell.frame.size.height
}
else
{
tableview_height.constant=tableview_height.constant+cell.frame.size.height
}
return cell
}
Check my answer on the almost same question.
How to increase the height of parent view according to height of UITableView in swift?
It is the best way to achieve what you want, because it does not depend on your table settings or if you have header/footer/custom insets/whatever.
Hope it will help.
I have a table view with 3 types of custom cells.
Interface in storyboard.
3 different classes in the project for the cells.
I'm doing this currently and the cells IBOutlets are coming out to be nil.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = ListCell()
cell.configureCell(Data[indexPath.row])
return cell
}
class ListCell : UITableViewCell {
#IBOutlet weak var selectButton: UIButton!
func configureCell(data: ParamList) {
selectButton.setTitle("Select " + data.name, forState: .Normal)
}
#IBAction func selectButtonPressed(sender: AnyObject) {
print(selectButton.currentTitle)
}
}
I don't want to reuse any cells because every cell has different properties.
Some have textboxes other have different interactive matter which needs to be submitted in the end to a webservice.
I want to create new cells in memory for every cell.
Max cells will be around 15. So won't have much of a memory problems.
Any way I can Do that??
I did finally solve this.
Here's what I did for the same.
I am describing my process if anyone else wanna do the same.
Warning, only do this if absolutely necessary and you do not have that many cells that can affect the performance.
For making UITableView's cells to remain in memory even if scrolled outside the screen encapsulate your table view in a scroll view, and set your UITableView's scrollEnabled to false.
If using Storyboards set a height constraint to your TableView and make an IBOutlet to your code file.
Programatically add new cells with different identifiers.
"\(indexPath.section)\(indexPath.row)"
After getting your data, set your tableView's height to a multiplier of your data count.
i.e.
tableViewHeightConstraint.constant = heightOfOneCell * data.count
tableView.delegate = self
tableView.dataSource = self
This way you can scroll with the scrollView and all your cell will still be in the memory.
Set nil inside the method dequeueReusableCellWithIdentifier. So you can get what number of cells you want in memory.
I'm trying to call [cell layoutIfNeeded] and [cell.contentView layoutIfNeeded] as I have a number of subviews that have custom constraint logic that I implement in the cell's layoutSubviews method.
However, despite calling both those methods in cellForRowAtIndexPath, when I check the frames of the subviews in the contentView, their frames are still incorrect. I've ensured to call layoutIfNeeded on each subview as well.
Any ideas on why this is happening? The frames are only correct after the cell is displayed, but the height isn't being calculated properly before that.
edit:
I am trying to use the new auto size feature in iOS 8. It's not resizing properly because I have some complicated logic in terms of where my labels go if one is larger than the other. It's not as simple as stacking the labels together - which is why I need the subviews to be laid out correctly before the height is calculated.
I'm not sure what is happening with the code without more information but you should consider using Auto resizing cells. This will resize your cells automatically without having to deal with layout subviews.
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
The layout subviews solution is still used in some edge cases but was mainly used before UITableViewAutomaticDimension came out.
I have been having an issue for quite some time with regards to an ios app I have been building in swift. I have a Uitableview ,with dynamic properties, embedded within my view controller. And what I want to do is size all of the cells to fill the table view. I have tried:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
tableView.reloadData()
let height = tableView.contentSize.height
return height
}
but this just returned zero for the height of the uitableview.
Help would be very appreciated.
You don't want to call reloadData() from this delegate method, since this method is getting called because the data is being reloaded.
In fact, you don't want to use this method at all if all of your cells are going to be the same height. Just set the table view's rowHeight property.
Assuming this is happening from a view controller, I'd override viewDidLayoutSubviews() to get notified when the table view size changes and set the row height there:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.rowHeight = tableView.bounds.height
}
You may or may not need to add reloadData() there to get the table view to update. Try it without it first. Setting the row height may automatically trigger a reload.
Also notice that I don't use contentSize to get the height. That's the height of all of the cells, and it's determined by the row height you set. So again, using it gets a little circular.