programmatically update Autolayout Constraints which is set via Inspector - ios

I have a ViewController which has a tableview in it. I set its autolayout manually. Now I'm trying to change the autolayout constraints programmatically. How can I do that?
This is my code's screenshot
Thanks

You can change constraints programatically without any outlet:
for (_, value) in self.view.constraints.enumerate() {
let constraint = value as NSLayoutConstraint
if constraint == .Height {
if value.firstItem.isEqual(self.tableView) {
constraint.constant = 200.0
}
}
}

Follow these steps
Just select the constraint you want to update progrmatically eg. height
create an outlet of it. New referencing outlet.
eg. #IBOutlet weak var heightConstraint: NSLayoutConstraint!
update constant, heightConstraint.constant = 100.

Set up outlets for the constraints you need to modify and hook them up.

Related

UITextView height won't change

I don't know why, but when I try to change the height of a UITextView there is no change at all.
CGRect frame = self.descView.frame;
frame.size.height = 500;
self.descView.frame = frame;
I have created the UITextView from storyboard and I used fixed height.
What am I doing wrong?
You can change your textview height using create an instance of height constraint of textview.
from storyboard first right click on height constraint of textview and create instance in class file like below
#IBOutlet var textviewHeight: NSLayoutConstraint!
then, easily you can play with its height
textviewHeight.constant = 500
UIView.animate(withDuration: 0.25) {
self.view.layoutIfNeeded()
}
If there are no autolayout conflicts the following code should set the correct height.
self.descView.heightAnchor.constraint(equalToConstant: 500).isActive = true

Resize UITableViewCell based on content availability in response

I have a self sizing UITableViewCell that displays blog posts.
A post consists of text and an image. The challenge I now have is that some posts do not contain an image.
How do I size the cell using Auto Layout? Perhaps should I set the UIImageView.isHidden = true instead?
Thanks!
Considering you said you are using auto resizing cells, following are the steps you should follow:
1) First subclass your tableview cell with custom UITableViewCell class
2) Take an outlet for UIImageView in above class as:
#IBOutlet weak var myImageView: UIImageView
3) Set the auto layout constraints to this image view from storyboard as leading, trailing, top and height constraint
4) Take outlet for height constraint of imageview in the same UITableViewCell class:
#IBOutlet weak var heightConstraint: NSLayoutConstraint!
5) In your cellForRow method, check if your data contains image or not. If no image is present, then change the value of height constraint:
if myImage == nil {
if myCustomCell.heightConstraint != nil {
myCustomCell.heightConstraint.constant = 0
myCustomCell.updateConstraintsIfNeeded()
}
}
This should work as expected. If not, please post the constraints you have applied.

Make a UIView relayout itself when dependent constraint changes

I have a UIImageView and UIButton, UIButton is aligned to top of UIImageView. Now in code I am changing the top of UIImageView but the UIButton is not updated accordingly. I tried SetNeedsLayout, LayoutIfNeeded on UIButton but nothing works.
override func viewDidLayoutSubviews() {
profileImageView.frame.origin.y = arcView.bounds.height/1.8
editProfileButton.layer.setNeedsDisplay()
}
I have set the constraints in Storyboard. I would really appreciate any help here.
First: Are you sure that all your constraints (for both the UIImageview and UIButton) are added right?
Second: when working the constraints, you should change the origin.y of the UIImageview also by by a constraint, by modifying its constant's value:
Instead of directly changing profileImageView.frame.origin.y, you should change the constant of the constraint that tells what's the imageview origin.y (if the first point is applied, this constraint must be exist...); Add this constraint to the viewController as an IBOutlet and change value of its constant property (take a look at the comments in the code snippet, it's a part of the answer):
class ViewController: UIViewController {
// let's assume that this is the #IBOutlet of the constraint, I called it 'imageViewTopMargin':
#IBOutlet weak var imageViewTopMargin: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
// it's not necessary -for sure- to do this the in the viewDidLoad method
// but I'm doing this for demo purposes:
// let's say that you want to push the imageView to the bottom with extra 40 points:
imageViewTopMargin.constant += 40
}
}
Hope this helped.

Change Swift constraint on if statement

Here is my tableview row/cell:
there are constraints set in place - the imageview is below the label and the button is below the imageview.
here is my code:
if(row == 1) {
imageview.hidden = false
} else {
imageview.hidden = true
//how can i change the button constraint from below imageview to below label?
Adding and removing constraints is really bad example for that. I'll make your UI more complex.
Best way of solving these auto-layout problems is adding two constraints. One from imageView to button and second from imageView to label.
Now after setting these constraints, you need to set their priority levels. So, let's say button will be below the imageView first. In this case, you need to set imageView to button constraint's priority to something like 750 or UILayoutPriorityDefaultHigh and label to button constraint's priority to 250 or UILayoutPriorityDefaultLow.
Let's start creating a custom UITableViewCell
class YourTableViewCell: UITableViewCell {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var button: UIButton!
#IBOutlet weak var buttonToLabelConstraint: NSLayoutConstraint!
#IBOutlet weak var buttonToImageViewConstraint: NSLayoutConstraint!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func shouldHideImageView(hidden: Bool) {
if(hidden == false) {
buttonToLabelConstraint.priority = UILayoutPriorityDefaultLow
buttonToImageViewConstraint.priority = UILayoutPriorityDefaultHigh
imageView.hidden = true
} else {
buttonToLabelConstraint.priority = UILayoutPriorityDefaultHigh
buttonToImageViewConstraint.priority = UILayoutPriorityDefaultLow
imageView.hidden = false
}
self.contentView.layoutIfNeeded()
}
}
After that, in your class where tableView is placed implement a logic like that:
if(row == 1) {
cell.shouldHideImageView(true)
} else {
cell.shouldHideImageView(false)
}
You should be all set.
You can try using a StackView, when you tell something to be hidden, the imageView the stack view will adjust the StackView as if the imageView was never a part of the view and it is an easy work around to not have to worry about constraints.
You can create IBOutlet on constraint and then just simply change the value like this:
buttonConstraint.constant = newValue
But i suggest you create for this a tableView. In this case you code and logic, i think, will be more accurate.
you could to this instead of hiding.
Make an outlet from the heights constraint of the imageview, call it constraint for now.
Set constraint.constant = 0 // effectively same as hiding.
Set constraint.constant = NON_ZERO_VALUE // effectively same as show.
hope it helps!
I see a couple of options. The first is a little easier to implement but a little less flexible if you decide to change your layout later.
Make the button's constraint to be below the label. Keep a reference to this constraint (you can connect it to your code via storyboard just like you do with the button itself, if you're using storyboard). When the imageView is visible, set myConstraint.constant += myImageView.frame.height. When the imageView is hidden, set myConstraint.constant -= myImageView.frame.height. Afterwards, call view.setNeedsLayout to update your constraints.
Make two constraints: one for below the image, and one for below the label ("constraintToImage" and "constraintToLabel"). Hook them both up to your controller like in option 1, and call view.addConstraint(constraintToImage) and view.removeConstraint(constraintToLabel) when the image becomes visible (and the opposite for when it's hidden). Again, call view.setNeedsLayout after.

Chaning height of UIView

I'm trying to change the height and width of UIView using Swift and it's not working. Tried both codes below, still no progress.
self.contentView.frame.size.height = 100
self.contentView.bounds.size.height = 100
contentView is a subview of the main view.
I guess you are using constraints. And when you use constraints you should change not the frame but constraints itself. It should looks like this:
In storyboard, pick height constraint for your view and create outlet to controller:
And then change it's constant value:
#IBOutlet weak var heightConstraint: NSLayoutConstraint!
func changeHeight() {
heightConstraint.constant = 200
// uncomment to perform changes with animation
// UIView.animateWithDuration(0.3) { () -> Void in
self.view.layoutIfNeeded()
// }
}

Resources