I've been looking for a lot of snippets in the net and I still can't find the answer to my problem. My question is I have a scrollView(SV) and I want to add a button inside scrollView(SV) programmatically with same width and height of its superview which is scrollView(SV) so that when user rotate the device button will have the same frame of scrollView(SV). how to do the NSLayout/NSLayoutConstraint? thanks
If someone is looking for a Swift solution – I would create a Swift extension for UIView
which will help you each time you want to bind a subviews frame to its superviews bounds:
Swift 2:
extension UIView { /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview": self])) } }
Swift 3:
extension UIView { /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) superview.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[subview]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["subview": self])) } }
Swift 4.2:
extension UIView { /// Adds constraints to this `UIView` instances `superview` object to make sure this always has the same size as the superview. /// Please note that this has no effect if its `superview` is `nil` – add this `UIView` instance as a subview before calling this. func bindFrameToSuperviewBounds() { guard let superview = self.superview else { print("Error! `superview` was nil – call `addSubview(view: UIView)` before calling `bindFrameToSuperviewBounds()` to fix this.") return } self.translatesAutoresizingMaskIntoConstraints = false self.topAnchor.constraint(equalTo: superview.topAnchor, constant: 0).isActive = true self.bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: 0).isActive = true self.leadingAnchor.constraint(equalTo: superview.leadingAnchor, constant: 0).isActive = true self.trailingAnchor.constraint(equalTo: superview.trailingAnchor, constant: 0).isActive = true } }
Then simply call it like this:
// after adding as a subview, e.g. `view.addSubview(subview)` subview.bindFrameToSuperviewBounds()
I'm not sure if this is the most efficient way to do it, but it works..
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.translatesAutoresizingMaskIntoConstraints = NO; // initialize [coverForScrolView addSubview:button]; NSLayoutConstraint *width =[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:0 toItem:coverForScrolView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0]; NSLayoutConstraint *height =[NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeHeight relatedBy:0 toItem:coverForScrolView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]; NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:coverForScrolView attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.f]; NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:coverForScrolView attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.f]; [coverForScrolView addConstraint:width]; [coverForScrolView addConstraint:height]; [coverForScrolView addConstraint:top]; [coverForScrolView addConstraint:leading];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With