I have a table view with various cells. They are all set to resize using
tableView.estimatedRowHeight = 45.0
tableView.rowHeight = UITableViewAutomaticDimension
For example if the cell is a label type and the label contains multiple lines of text, the label will expand and cause the cells height to increase. I have just created a new type of cell with a collection view inside it. It works great however the problem is that when more cells are added the collection view it's frame doesn't grow in size and thus the cell's height doesn't expand. Instead the collection view just becomes scrollable. Is there a way to make the collection view frame expand as more cells are added instead of making it scrollable? Any pointers on this would be really appreciated! Thanks!
You can set a constraint to the collection view and then resize it by code.
#IBOutlet weak var collectionViewHeightConstraint: NSLayoutConstraint!
let height = cells.count * a //a = height of the cells within the collection view
collectionViewHeightConstraint.constant = CGFloat(height)
Related
I am creating a collection view full of menu items. The collection view is supposed to be tall enough so that it fits perfectly in the size of view.
I can set the UICollectionView with a fixed height constraint, but if there are 20 items then that height might be too small or if there are 5 cells the height would be too big.
Is there a way to change the frames of the main view and the Collection view based off how many cells the view will have? Possibly in the viewDidLoad() function?
set the height constraint of the collection view in storyboard with any value , and hook it as IBOutlet say collectionHCon
override func viewDidLayoutSubviews() {
self.collectionHCon.constant = numberOfItems * itemHeight
super.viewDidLayoutSubviews()
}
I have a UITableView with cells that have inside a UICollectionView.
Now all works great except of UICollectionViewCell scrolling i want that the height of table view cell follow the Collection view cell content.
In simple word i want scrolling in table view but not inside single cell i need to display all contents of UIcollectionViewCell without scrolling inside it.
Thanks
You have to calculate the collectionviews' heights and set a height constraint on each of them. then add top and bottom constraints from the collectionviews to their superviews (the tableviewcells / their contentviews) and let autolayout do its work.
don't forget
tableView.estimatedRowHeight = 44 // or something similar
tableView.rowHeight = UITableViewAutomaticDimension
in the controller's viewDidLoad to make the automatic row height calculation work.
I'm building a View Controller with some elements of UIView and one UITableView. This view will be larger than an iPhone screen than I put all those elements in a UIScrollView and configured auto layout.
The number of rows in a UITableView are dynamic, and I need that all content be visible in a single screen. I don't want to enable UITableView scroll property because will be complete messy working with master UIScrollView and the UITableview scroll
I have been researching for days on StackOverflow for posts about this problem and couldn't find anything like my problem.
This is the code trying to resize UITableView and UIScrollView
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Configuring dataSource an delegate
self.tableView.dataSource = self
self.tableView.delegate = self
// Sizing all the elements inside scrollView
var contentRect = CGRectZero
for view:UIView in self.scrollView.subviews {
contentRect = CGRectUnion(contentRect, view.frame)
}
print(contentRect)
// Trying to resize the tableView and scrollView to fit more contents
self.tableView.contentSize = CGSizeMake(scrollView.frame.width, CGFloat(441))
scrollView.contentSize = CGSizeMake(scrollView.frame.width, CGFloat(877))
scrollView.delaysContentTouches = true
scrollView.canCancelContentTouches = false
// Looking for a new size and nothing change
var contentRect2 = CGRectZero
for view:UIView in self.scrollView.subviews {
contentRect2 = CGRectUnion(contentRect2, view.frame)
}
print(contentRect2)
print("Tableview width \(self.tableView.frame.width)")
print("Tableview height \(self.tableView.frame.height)")
}
The sample project on GitHub
I appreciate any help
Layout of ViewControl:
The short, but wrong answer to this question is to add an autolayout constraint to the tableview constraining the height to a constant size. You can set it to your best guess, but at runtime set it equal to the tableview's content size's height.
The problem with this approach is that it completely eliminates the benefit of tableview's and reusable cells. Table views are expressly designed to minimize the memory footprint of your view. It takes a lot more memory to store the view (cell) that represents your data than it does to keep track with data you're filling these cells in with.
So instead, the better solution is to use multiple sections within a table view. Using the example from your screenshot, your parent scroll view will be a tableview instead of a scroll view. It would have four sections. In the first section, we return a single row with the yellow view which is configured as a table view cell, and we do the same in the third & fourth sections. In the second section, we return however many rows you were using in the table view.
Alternatively, the yellow view could be thought as the table header, and the blue & red views become the table footer, with the rows in the middle.
Inside the ScrollView are two Labels (multilateral), and below it the TableView (in which the number of rows may be different).
The height of both Label and TableView is not set.
All outlets set constraints on the indents from each other above and below, including a View of the container.
In summary: both Labels height correct, but TableView is obtained with a height of 0 (not visible). It is only visible if the height is explicitly set. The number of rows of the TableView is determined correctly.
How can I programmatically set the height of the TableView to show it? ("row height" x "number of cells")? I know the height of row in TableView.
You are referring to the contentSize's height of the table view.
First you need to add a height constraint for the table view.
Then after the table finishes loading, do this :
self.tableViewHeightConstraint.constant = self.tableView.contentSize.height;
I have a non scrolling UITableView inside of a larger UIScrollView. Since the table view is non scrolling, I want its frame size to always match its content size.
I have the following method that I call:
- (void)resizeTableViewFrameHeight
{
// Table view does not scroll, so its frame height should be equal to its contentSize height
CGRect frame = self.tableView.frame;
frame.size = self.tableView.contentSize;
self.tableView.frame = frame;
}
The problem is that I must be calling this method at the wrong time (before the contentSize is set). I was wondering, is there a property that I can set on UITableView that will cause its frame to always match its content size automatically?
There is no property that dynamically adjusts table view's frame. Also, I do not think that a UITableView can calculate its entire contentSize up-front because a table view could be practically infinite in size, depending what is specified from its datasource and other delegate methods such as heightForRowAtIndexPath. These methods can be dynamic, making it virtually impossible to predict the entire size of a table view.
I conclude that you are perhaps not using this UI element correctly.
Workaround:
By having the frame of the table view constrained to the visible area of the scroll view you could simply allow it to scroll. Perhaps you need to prevent your scroll view from scrolling while the table view is scrolling and vice versa. You could easily do this in the UIScrollView delegate methods.
I needed to do something like this in iOS 8: A scroll view that contained a non-scrolling fixed-width table view with variable number of rows of content, so I wanted to dynamically resize the height of the table view.
What worked for me was to set up a height constraint on the table view with a dummy value, and then create outlets to both the table view and the constraint. Then this was all I needed:
class ViewController: UIViewController, UITableViewDataSource {
#IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint!
#IBOutlet weak var tableView: UITableView!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
tableViewHeightConstraint.constant = tableView.contentSize.height
}
// (plus additional data source methods, etc.)
}
I can imagine situations (maybe with lots of rows, or rows of variable height) where it might not be this simple, but this worked for me.