Collapse Expand UITableView - ios

I tried to expand/collapse an UITableView that is inside an UIViewController. I put the UITableView height constraint to zero and make the animation
func collapseExpandRoomSection() {
isRoomCollapsed = !isRoomCollapsed
tableHeightConstraint.constant = isRoomCollapsed ? 0.0 : totalTableHeight
UIView.animateWithDuration(0.3) {
self.view.layoutIfNeeded()
}
}
The collapse effect works fine but when I tried to expand the table all the cells are gone.
Thanks

Look like you have updated the constraint, You should be doing it in this order I believe:
self.view.setNeedsUpdateConstraints()
self.view.setNeedsLayout()
self.view.layoutIfNeeded()
As you have updated the constraint, therefore you should firstly update the set update constraints and set needs layout. Followed by the layoutIfNeeded() to have the change apply immediately.
As discussed briefly on the comments, the code is only applicable if you override the updateConstraint. Is not correct in answering the question above.

Related

How do I update a constraint from the Storyboard without an IBOutlet or Identifier?

I have a lot of views that are created in the storyboard, but I want them to be able to update their constraints dynamically without having to use an IBOutlet each time.
I started by making a custom class for the superview of the view I want to update, and change its subview's bottom constraint like this:
myView.constraints.filter{ $0.firstAnchor is NSLayoutAttribute.bottom }.constant -= 200
'NSLayoutAttribute.bottom' doesn't seem to be the correct way to check the type of the Anchor.
How do I check the type of the constraints I want to change?
Am I correct in updating the constraints in the superview of the view I want to change, not the view itself?
NSLayoutConstraint from iOS7 have a property called identifier, from code or from IB you can set this property.
After that to get the constraint you are looking for is just a matter of searching it in a particular view.
Consider this UIView extension:
func constraint(withIdentifier:String) -> NSLayoutConstraint? {
return constraints.filter{ $0.identifier == withIdentifier }.first
}
As per dahlia_boy's suggestion, I used UIView.animate to achieve this functionality, however it doesn't seem to be permanent:
translatesAutoresizingMaskIntoConstraints = true
UIView.animate(withDuration: 1, animations: {
self.frame.size.height -= 200
})

How to get resizing tableView cell with different content without deleting constraints in iOS

I have tableView cell with different content(views, labels, imageViews) in one cell. But in something cells content can be not full. How can i use resizing cells without removing and adding always constraints? Thanks.
One of possible solutions for this problem:
Add constraints for hidden state with priority 1000
Add extra constraints for resized state with lower priority (ex 750)
Save constraints that is ONLY for hidden state into IBOutlet collection
Save constraints that is ONLY for resized state into another IBOutlet collection
Code:
#IBOutlet var hiddenConstraints: [NSLayoutConstraint] = []
#IBOutlet var visibleConstraints: [NSLayoutConstraint] = []
func hide(_ hide: Bool) {
for hiddenConstraint in self.hiddenConstraints {
hiddenConstraint.isActive = hide
}
for visibleConstraint in self.visibleConstraints {
visibleConstraint.isActive = !hide
}
self.layoutIfNeeded()
}
There is faster solution:
Move content that can be hidden into container view
Set height constraint for container view
Change from code height constraint constant to 0 if hidden or to proper height if visible
Code:
#IBOutlet var heightConstraint: NSLayoutConstraint!
func hide(_ hide: Bool) {
self. heightConstraint.constant = hide ? 0 : 150 //Estimated height
self.layoutIfNeeded()
}
This is not a good approach, as it will lead to constraint crashes at runtime. So I prefer to use first one.
Also you will need to update your cell from table to move other cells up or down.
Ray Wenderlich has a fantastic tutorial on dynamic sizing of table cells that can be found here:
https://www.raywenderlich.com/129059/self-sizing-table-view-cells
TL;DR You need to make sure your cell's content is pinned on all four sides to the cell's content view, as well as setting as high priority vertical hugging, greater than or equal to height constraint on your label.

Swift: removefromSuperview removes constraints

Currently working on some swift program and I've a call to action where I remove a blurview from the superview and at the same time I'm animating 2 buttons.
Everything works like it should but there is one small problem. When I remove the blurview from my superview the constraints on my 2 buttons are being set to 0 on the bottom and animating from that position.
I don't want them to shift to 0. If I don't remove the blurview my animation is working perfectly. I've checked if my button constraints are related to the blurview, but that isn't the case. Because I assumed that it could only reset my constraints when they are relative to the blurview.
My storyboard looks the following:
view
|-> camera_view
|-> blur_view
|-> record_label
|-> record_button
The code that I'm executing is the following:
#IBAction func recordButton(sender: AnyObject) {
self.blurView?.removeFromSuperview()
UIButton.animateWithDuration(0.3, delay: 0.2, options: .CurveEaseOut, animations: {
var recordButtonFrame = self.recordButton.frame
var recordLabelFrame = self.recordLabel.frame
recordButtonFrame.origin.y -= recordButtonFrame.size.height
recordLabelFrame.origin.y -= recordLabelFrame.size.height
self.recordButton.frame = recordButtonFrame
self.recordLabel.frame = recordLabelFrame
}, completion: { finished in
print("Button moved")
})
}
What am I doing wrong?
Kind regards,
Wouter
Instead of removing blurView from superview you could hide it.
Replace
self.blurView?.removeFromSuperview()
with
self.blurView?.hidden = true
The problem is that you're animating frames while using constraints. You should be animating constrain changes / constraint constant value changes.
When you don't remove the view the layout isn't recalculated so your frame animation 'works'. It isn't correct and will get reorganised at some point in the future.
When you remove the view the layout is recalculated and everything moves around before your animation starts.
You don't give details of your constraints but it seems likely that you should be animating constraints before removing the view, then removing and ensuring the constraints are all sane on completion.

Why is a UIScrollView not scrolling vertically (using Auto Layout)?

My view hierarchy is
UIView
UIScrollView
UIView1
-->UIView1.1
-->UILabel
-->UILabel
-->UILabel
-->UILabel (bottom)
I am using Autolayout. I have tried all the ways and searched a lot. I did connect the bottom UILabel to the Bottom Layout of the UIView1 and set its priority to the 750 (the lowest of all). I have almost tried everything which is said on this forum and everywhere because everybody is saying same thing.
I am also adding the one view dynamically in UIView1.1.
I have no idea why this is not working. Scrollview is not scrolling properly.
Please help me. I am stuck on this for 3 days.
To make this work is actually quite easy. You do not need to put all labels into an extra view. And you do not have to set the contentSize yourself. Auto Layout will do that for you.
You just have to make sure to have the following things:
Each label and the view on top of the labels have to have a
width constraint that is set to the width of the scroll view and a left constraint with value 0 (or any padding you might want to add)
The view on top needs a top constraint of value 0
The bottom label needs a bottom constraint of value 0
And that's all!
Here's a sketch to show the constraints:
In case you are using Masonry or SnapKit for your Auto Layout here is how those constraints would be added in code:
topView.snp_makeConstraints { (make) -> Void in
make.top.equalTo(0)
make.left.equalTo(0)
make.width.equalTo(scrollView)
}
label1.snp_makeConstraints { (make) -> Void in
make.top.equalTo(topView.snp_bottom)
make.left.equalTo(0)
make.width.equalTo(scrollView)
}
label2.snp_makeConstraints { (make) -> Void in
make.top.equalTo(label1.snp_bottom)
make.left.equalTo(0)
make.width.equalTo(scrollView)
}
label3.snp_makeConstraints { (make) -> Void in
make.top.equalTo(label2.snp_bottom)
make.left.equalTo(0)
make.width.equalTo(scrollView)
make.bottom.equalTo(0)
}
scrollView.contentSize=CGSizeMake(320,758);
scrollView.contentInset=UIEdgeInsetsMake(64.0,0.0,44.0,0.0);
Finally these lines saved me.
Working tried out.
if you are not using autolayout then put it only viewDidLoad():
[_mainScroll setContentSize:CGSizeMake(320, 2000)];
or if you are using autolayout then follow this:
First give constrains to scrollview top,bottom,leading and trailing. Now take one more view and give same constrains as scrollview given by you earlier.
Don't forgot to give additional constrain for that view fix height and width equal to main parent view.
or
Just watch this.
https://www.youtube.com/watch?v=rjTS9fyWqdg

Why isn't my tableview row height being set properly?

I am trying to make a table view with a dynamic cell containing an image view and 3 labels in Interface Builder, but for some reason the table view row height isn't being set properly and all the content is being cut off. This is the only code for it:
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 100.0
}
And my interface builder constraints are almost similar to the ones shown below from a Ray Wenderlich tutorial (http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift)
Here is a sample of the simulator output:
If anyone has any insight on how I can fix this, I'd be more than happy to hear you out. As you probably guessed, I am trying to make it so that the cell height expands according to the subtitle length (a la Twitter) but to no avail :( Thanks!
Update: It looks a bit better now but still not expanding as the UILabel expands :(
In the UIViewController which has your UITableView as a child view(or it can be UITableViewController) make your table view cell height "100" too.I think it is 44 now?
Also if it not set already, set your subtile's "Lines" property to "0" in Interface Builder to make it self-sizing.
You are using the estimatedrow height. There is an another delegate method for height that you have to use. It is just rowheight delegate. Use heightForRowAtItem index version of objective c in swift.
Solved it! My constraints were correct but for some odd reason the tableView wasn't updating. Adding the following code seemed to make it fine:
override func viewDidAppear(animated: Bool) {
tableView.reloadData()
}
If you have any better suggestions feel free!

Resources