UIStackView zero height although I have content in it - ios

I have UIStackView in UITableViewCell and have four long text labels in it.
In first load I show only first label with 44 height in cell and hide other three and StackView shows properly.Then when I click on tableViewCell I need to expand cell and show other three labels. I show them and reload TableView but my StackView has zero height after that and all four label have zero height too. I hit this problem only with IOS 10.1 and when I use labels with short text StackView work well.
This is my code:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var cell = tableView.cellForRowAtIndexPath(indexPath) as! AboutUsTableViewCell
cell.firstLabel.hidden = isExpanded
cell.secondLabel.hidden = isExpanded
cell.thirdLabel.hidden = isExpanded
isExpanded = !isExpanded
tableView.reloadData()
}
Thank you all!

You should update table after changing isHidden properties. That's should do a trick.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var cell = tableView.cellForRowAtIndexPath(indexPath) as! AboutUsTableViewCell
cell.firstLabel.hidden = isExpanded
cell.secondLabel.hidden = isExpanded
cell.thirdLabel.hidden = isExpanded
isExpanded = !isExpanded
tableView.beginUpdates()
tableView.endUpdates()
}
Also, check this article about using UIStackView inside UITableView cells

Set the Labels number of lines to 0 and add below code to the viewDidLoad method.
self.tableView.estimatedRowHeight = 44.0 //or cell height
self.tableView.rowHeight = UITableViewAutomaticDimension

Related

How to adjust label height and width in custom tableView Cell

I have a expandable tableView, in which when i expand a section, than there are three cell. On firth Cell there is only name and in second cell. It have a big content. Now I want to auto adjust this label height and width according to content.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tblView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
let dataArrayTblView = dataArrayForTableView
let titleName = dataArrayTblView.valueForKey("name")
let dueDate = dataArrayTblView.valueForKey("deadlinedate")
let description = dataArrayTblView.valueForKey("description")
cell.titleLabel.text = titleName[indexPath.row] as AnyObject! as! String!
cell.dueDateLabel.text = dueDate[indexPath.row] as? String
cell.descriptionLabel.text = description[indexPath.row] as? String
cell.descriptionLabel.sizeToFit()
cell.textLabel?.backgroundColor = UIColor.clearColor()
cell.selectionStyle = .None
return cell
}
But not getting complete content
Try to set this. It will automatically adjust the height of the row for you. If it is not working, then you have something wrong with your constraints inside your storyboard.
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 40
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
You should use UITableViewAutomaticDimension as row height something like,
// this should be set in viewDidload
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
for that you must use autolayout and should set proper constraints to your label in cell.
Constraint should be in linear chain, I mean your label's top and bottom both constraint must be set and your label should resize according to content so your cell will resize accordingly!
You can refer Self-sizing Table View Cells by Raywenderlich !
Put below in viewDidLoad and set autolayout as per below screenshots.
tblview.rowHeight = UITableViewAutomaticDimension
tblview.estimatedRowHeight = 44
Screenshot 1
Screenshot 2
Screenshot 3
Screenshot 4
Use heightForRowAtIndexPath method to adjust height of row. Calculate
size of string with boundingRectWithSize this method. example:
Try This:
if let YOUR_STRING:NSString = str as NSString? {
let sizeOfString = ns_str.boundingRectWithSize(
CGSizeMake(self.titleLabel.frame.size.width, CGFloat.infinity),options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: lbl.font], context: nil).size
}

How to support auto resizing UITableViewCell with a UILabel in it

I am trying to figure out how get the correct height for my tableview cell that contains a uitextview so that all the content in the uitextview will be display. The textview is not editable and not scrollable, which means that the string for the uitextview is known. I tried simply returning the height of the tableview cell that is in the storyboard in heightForRowAtIndexPath but that cuts off the content if it is too large. I also tried calculating the height for the textView in heightForRowAtIndexPath but it throws an error at runtime:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let cellInfo = UserCellsArray[indexPath.section]
switch cellInfo {
case .userInfo: return 104
case .ubio:
let cell = tableView.dequeueReusableCellWithIdentifier(cellInfo.description, forIndexPath: indexPath) as! UserProfileTableViewCell //error
let oldHeight = cell.userBio.frame.size.height
cell.userBio.text = self.bio
var bodyframe = cell.userBio.frame
bodyframe.size = cell.userBio.contentSize
let newHeight = cell.userBio.contentSize.height
return tableView.rowHeight - oldHeight + newHeight
}
}
Here is what you need to do:
Need to use auto layout in your cell and set up appropriate constraints for UILabel. Since we want to resize the UILabel to fit the text set to it, we will set the number of lines value to 0. And then set the leading, trailing, bottom and top constraints to the UILabel. Please see screenshots here:
In your Table View controller > viewDidLoad call these two lines:
tableView.estimatedRowHeight = 50.0 //Give an approximation here
tableView.rowHeight = UITableViewAutomaticDimension
and also implement delegate method:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{
return UITableViewAutomaticDimension
}

Change cell height by the content of the textView inside the cell

I have a Table View called todoTableView with cells that created by the user.
Each cell has Text View.
I want to change the height of the cell by the content of the Text View.
This is what I tried:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: TableViewCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath:indexPath) as! TableViewCell
cell.bounds.size.height = cell.textView.bounds.size.height
return cell
}
Bound Your textview with cell from all sides using marginal constraints.(Leading, Trailing, Top and Bottom constraints)
Disable textView Scrolling
In viewDidLoad() add the following.
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension
This will make your cell size according to your textview content size.
Have a look at result :
You don't need to write heightForRowAtIndexPath.
Irfan's answer didn't work for me.
It works after I go to Size Inspector and check "Automatic" for "Row Height".
You should also implement heightForRowAtIndexPath:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return // Calculate your custom row height here.
}

Dynamic table view cell, change of subview height programmatically

I have a UITableViewCell with a custom view cell.
In this view cell, I have a simple UIView called imgWrapper where I added constraints as follows:
width = 50
height = 50
leading to superview = 20
top to superview = 20
bottom to superview = 20
Those are the only constraints in there. And I left the hugging and compression to the default ones.
In my code I've set this:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 90
}
Then in in my rowAtIndex...I have this:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: LogCustomCell = tableView.dequeueReusableCellWithIdentifier("logCustomCell", forIndexPath: indexPath) as! LogCustomCell
var imgWrapperHeight: CGFloat = log.big ? 100 : 50
cell.imgWrapperHeight.frame.size.height = imgWrapperHeight
return cell
}
Once I compile and run it. All the cells are the same size.
Notes:
I checked if log.big was true/false and it does change.
I've also tried to do CGRect(x,y,width,height) but also didn't work.
I know I can do heightForRowAtIndexPath but I want to do animations and I know we can do something like this for labels (see printscreen) which makes the tableView know the height without defining it:
Any ideas what I'm doing wrong?
You need to put your height logic into the UITableViewDelegate method called tableView:heightForRowAtIndexPath, something like the following:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return (true ? 100 : 50) + 2 * 20
}
PS. I've written this in Swift 2, thus the overridekeyword.
Delegate method "heightForRowAtIndexPath" will do it for you. You can know cell index for which you are returning height from indexPath.row and hence return height accordingly.
i.e
if indexPath.row == 0
{
return 70
}
else if indexPath.row == 1
{
return 100
}
add
self.automaticallyAdjustsScrollViewInsets = false
before these two lines
tableView.estimatedRowHeight = 50
tableView.cellHeight = UITableViewCellAutomaticDimension
Solutions 1:
As mentioned by the users. You can set the row height in your UITableViewController like so:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return (true ? 100 : 50) + 2 * 20
}
Solution 2:
Set the height constraint on the element that will determine the height of cell. Then create an outlet in your VC for NSLayoutConstraint
While you are setting the content of the cell, you can do:
Ex:
#IBOutlet var imgWrapperHeightConstraint: NSLayoutConstraint!
...
override func tableView(tableView: UITableView, cellAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
imgWrapperHeightConstraint.constant = 50 // Or whatever value you want
}

Designing tap-to-expand cell in storyboard

I have added a feature to my app that allows users to add notes which will appear in table view cells when they are tapped as they expand to show more content.
My question is - How do I layout the content that is to be shown when the cell is expanded? I have tried adding the textView to the prototype cell, but I just get the textView overlapping on the other cells in the table view rather than being hidden before being tapped.
Here is my code for when a cell is tapped:
var selectedRowIndex: NSIndexPath = NSIndexPath(forRow: -1, inSection: 0)
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRowIndex = indexPath
tableView.beginUpdates()
tableView.endUpdates()
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.row == selectedRowIndex.row {
if cellTapped == false {
cellTapped = true
return 141
} else {
cellTapped = false
return 70
}
}
return 70
}
You need to set the cell's clipToBounds property to YES (or select the "Clip Subviews" check box in IB for the cell), so none of its subviews will show outside the bounds of the cell. The text view should have constraints to the sides of the contentView as well as a height constraint. It should also have a constraint to something above it, and that view should have a constraint to the top of the contentView. The constraints should look something like this,

Resources