I have been adjusting the constraints for a custom table view cell and I am not getting the output I want. This is what I have so far:
I didn't add the constraints yet for the number labels. And this is what I have in the UITableViewController class:
override func viewDidLoad() {
super.viewDidLoad()
let cellNib = UINib(nibName: "SummaryCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "SummaryCell")
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 88
}
As for the size inspector describing the SummaryCell.xib file, I set the Table View Cell row height to be 88, with the custom box checked, and the view has a "Show" of "Frame Rectangle," with a width of 414 and height of 88, which I am building for a iPhone 7+/8+ view and shows up fine without constraints. I know constraints will be needed for other screens sizes, and adjusting constraints has been a nightmare so far. Can anyone help?
Related
I've created a UICollectionView through the storyboard and temporarily positioned it in the view; however, I'd like to overwrite the positions programmatically on launch rather than using the storyboard configuration.
I thought viewDidLoad() was the right location to place make this change?
Swift 2 Code:
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell")
collectionView.backgroundColor = UIColor(white:1, alpha:0.0)
// Doesn't stretch the width to the device's width on launch. :-(
collectionView.frame.size = CGSize(width: UIScreen.mainScreen().bounds.width, height: 200)
}
If you are setting constraints and then want to change height or width then you should take outlet of that height or width and increament it's constant value. just ctrl+drag from width constraint to class and make outlate and then increment that outlate's contant property in viewdidload.
for example,
#IBOutlet weak var heightConstraint: NSLayoutConstraint!
self.heightConstraint.constant = 200
And second thing if you want to keep your collectionview's height equal with device then there is no need to set programatically. autolayout manage it if you set proper constraint. so main point is use autolayout at evrywhere or not at all. dont mix both autolayout and then set frame programatically.
hope this will help :)
I am designing a page having a scroll view and above it a table view(scroll disabled). For doing this I have referred answers in this question - Make UITableView not scrollable and adjust height to accommodate all cells ,but wasn't successful.
Hierarchy of views along with provided constraints-
-Main View
-Scroll view
pinned to all sides of main view(0,0,0,0), constraint to margins
-Content View
pinned to scroll view(0,0,0,0),equal width to main view,equal height to main view(priority - 250)
-Table view inside content view
scroll disabled,having 50 point spaces from all sides,Height(>=),bottom spacing 50(relation >=).I have put greater than equal so as to increase height dynamically.
Now when I populate my table view I use the code as
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableview.dequeueReusableCellWithIdentifier("cellreuse", forIndexPath: indexPath)
cell.textLabel?.text = name[indexPath.row]
tableview.frame.size = tableview.contentSize
return cell
}
So when I run my code, it increases the tableview frame but doesn't stretch the content size and it just becomes weird as my scroll view doesn't scroll to the end of the table view neither my table view obeys the auto layout constraints.
Just I needed to do this -
remove the line - tableView.frame.size = tableView.contentSize
Add a height constraint for table view.
Set priority to High
Create an outlet of the height constraint(Ctrl+Drag).
Wherever you need to reload data of your table, set the height constraint to tableview's content height.
tableHeightConstraint.constant = tableview.contentSize.height
Assign a table height. Let it be constant 0.
Just add below lines.
tableView.heightConstant.constant = CGFloat.greatestFiniteMagnitude
tableView.reloadData()
tableView.layoutIfNeeded()
tableView.heightConstant.constant = tableView.contentSize.height
With this, you can easily achieve dynamic table height. Working on iOS 13, Swift 5.
Had the same issue and resolved it by doing the following:
Create an outlet of the height constraint for the table view with a priority of 1000
#IBOutlet private weak var tableViewHeight: NSLayoutConstraint!
On viewDidLayoutSubview call layoutIfNeeded on the table view and then set the table view height constraint to the height of the content view
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.layoutIfNeeded()
tableViewHeight.constant = tableView.contentSize.height
}
Tested on iOS 14.1 and iOS 16.1
I'm using Nibs with my tableview for the header and cell
tableView.registerNib(UINib(nibName: "CategoryCell", bundle: nil), forCellReuseIdentifier: "catcell")
tableView.registerNib(UINib(nibName: "CategoryHeaderCell", bundle: nil), forHeaderFooterViewReuseIdentifier: "catheader")
and setting up autolayout in the storyboard. theres a label and uiswitch aligned to each side.
I'm not getting contstraint errors, before someone suggests Correct subclassing and autolayout of UITableViewHeaderFooterView as a solution.
The problem is that the header cell is not filling the tableview, while the normal cell is. You can see a shortened header view below.
in my header subclass, ive tried a few things but they dont work.
override func awakeFromNib() {
super.awakeFromNib()
.....
self.contentView.autoresizingMask = UIViewAutoresizing.FlexibleWidth
self.autoresizingMask = UIViewAutoresizing.FlexibleWidth // this doesnt help
self.setWidth(414)
self.contentView.setWidth(414) // none of these change the size
}
I can't center a view that has been placed as a subview of a UITableView's tableHeaderView in a storyboard using auto layout.
In a storyboard, I have a UITableView. I dragged a UIView (the red view) to the top, released, and it created a table header view automatically. I then dragged and dropped another UIView (the yellow view) on top of the table header view, resized, and applied some constraints to ensure it stays centered:
When I run the app on the simulator, here's what I get:
The yellow view is obviously not centered. However, the "Filter" button at the bottom is.
I know it's tricky to get the height right using auto layout and storyboards and table header views (and you can see that the height of the red view is definitely incorrect), but at this point, I'm just trying to solve for horizontally centering my yellow view.
Am I able to set this all up in my storyboard without having to configure my constraints in code?
Make sure that your UITableView has the leading, trailing, bottom, top constraints set up against its superview.
Check the table header view and all sub views have Autoresize Subviews enabled:
You can also force the table to re-render the header view by re-setting it to the same view:
[self.tableView setTableHeaderView:self.outletToHeaderView];
Update: to resize the table header view, give give it an appropriate frame in viewWillAppear:
CGRect newFrame = self.outletToHeaderView.frame;
newFrame.size.width = self.tableView.bounds.size.width;
newFrame.size.height = 44;
[self.outletToHeaderView setFrame:newFrame];
// Then reset it to force the table view to re-render/accommodate
[self.tableView setTableHeaderView:self.outletToHeaderView]
In your file TableViewHeader:
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
yourView.translatesAutoresizingMaskIntoConstraints = false
yourView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
}
You need to use prototype cell from table view, than dequeue it with reusable identifier and return it contentView. Only that's do the trick
var headerView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.headerView = (self.tableView.dequeueReusableCellWithIdentifier("CustomHeaderCell") as! UITableViewCell).contentView
}
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return self.headerView
}
upd:
Oh sorry, my example is written in Swift. But it's easy to understand how to do the same in Obj-C
I have a table view with a bunch of cells (custom cell, which only has its content view).
In tableView:cellForRowAtIndexPath: I'm adding a predefined UIView (which has several subviews) to the content view of the custom cell. I set up all constraints for the UIView and its subviews before.
Last but not least, I set the vertical and horizontal constraints for the content view of my custom cell (superview) and the UIView, which was added before (subview).
The constraint strings look like this:
H:|[view]|
V:|[view]|
Unfortunately, I still get the default height for all table view cells. I'm wondering If there's a way to let auto layout do the calculation of the height automatically according to content size.
Check out my detailed answer to this question here: https://stackoverflow.com/a/18746930/796419
It takes a bit of work to set up, but you can absolutely have Auto Layout constraints driving a completely dynamic table view without a single hardcoded height (and let the constraint solver do the heavy lifting and provide you with the row height).
Auto Layout won't help with the cell height. You'll need to set that in tableView:heightForRowAtIndexPath. I guess you're probably asking this because your cell heights are variable, not fixed. i.e., they depend on the content.
To resolve that, pre-calculate the cell heights and store them in an array. Return the value for the appropriate indexPath in the tableView:heightForRowAtIndexPath method.
Be sure to calculate content sizes on the main thread, using sizeThatFits of UILabel classes and such like.
If your calculation is intensive, do the majority of it off main apart from the view related methods such as sizeThatFits.
I solved the problem by using CGSize size = [view systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; in tableView:heightForRowAtIndexPath:.
To set automatic dimensions for row height, ensure following steps to make, auto dimension effective for cell/row height layout.
Assign and implement dataSource and delegate
Assign UITableViewAutomaticDimension to rowHeight & estimatedRowHeight
Implement delegate/dataSource methods (i.e. heightForRowAt and return a value UITableViewAutomaticDimension to it)
Swift:
#IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Don't forget to set dataSource and delegate for table
table.dataSource = self
table.delegate = self
// Set automatic dimensions for row height
// Swift 4.2 onwards
table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = UITableView.automaticDimension
// Swift 4.1 and below
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Swift 4.2 onwards
return UITableView.automaticDimension
// Swift 4.1 and below
return UITableViewAutomaticDimension
}
For label instance in UITableviewCell
Set number of lines = 0 (& line break mode = truncate tail)
Set all constraints (top, bottom, right left) with respect to its superview/ cell container.
Optional: Set minimum height for label, if you want minimum vertical area covered by label, even if there is no data.