Scuttle
Scuttle

Reputation: 165

How do i make the constraints resize the buttons correctly?

I've added a stoplight image and red, yellow, and green buttons. I want to have the buttons resize to iPhone 4S and iPhone 6S screens, but the buttons either disappear off the page or are the wrong size for the iPhone 4S. I thought the number of point would resize proportionately, but it appears it does not. Any help would be appreciated, I really want to understand constraints but I am just not getting it! Normally I would just do a x-position/screensize, y-position/screensize to relocated it, but this could be noticeably too long.

Red light goes oblong

Green light shrinks too tiny

Here is the constraints of the latest incorrect location. When I try to select the stoplight image, it won't provide a constraint for the leading and trailing edge to the stoplight image.

Red light Wrong size and location

The yellow button is placed against the stoplight image, but it won't resize.

Yellow light Wong size and location

Upvotes: 1

Views: 251

Answers (2)

Carien van Zyl
Carien van Zyl

Reputation: 2873

The easiest solution would be to give all images fixed values for their width and height constraints. Then you can align the spotlightImage in the superview as you wish and define the alignment of the circle images relative to the stoplight image.

However, if you would like to stretch the width of the stoplight image depending on the width of the screen, this is a complex problem. I played around a bit trying to define all constraints in storyboard, but could not come up with a proper solution. What one ideally would like to do, for example, is define the centreX of the circles proportionally to the spotlight image's width. Similarly for the y position. Unfortunately this is not possible.

In code one have a little bit more control. Here is a solution that will work. It is not pretty, because you are actually recalculating the width of the spotlightImage, but it works :-)

class ViewController: UIViewController {

    lazy var stopLightImageView: UIImageView = {
        return UIImageView(image: UIImage(named:"stopLight"))
    }()

    lazy var circleImageView: UIImageView = {
        return UIImageView(image: UIImage(named:"circle"))
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
    }

    private func setupViews() {
        //Values at start.  This is used to calculate the proportional values, since you know they produce the correct results.
        let stoplightStartWidth: CGFloat = 540
        let stoplightStartHeight: CGFloat = 542
        let circleStartWidth: CGFloat = 151
        let circleStartLeading: CGFloat = 231
        let circleStartTop: CGFloat = 52

        let screenWidth = UIScreen.mainScreen().bounds.size.width
        let stoplightMargin: CGFloat = 20

        self.view.addSubview(stopLightImageView)
        stopLightImageView.translatesAutoresizingMaskIntoConstraints = false

        //stoplightImage constraints
        stopLightImageView.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor, constant: stoplightMargin).active = true
        stopLightImageView.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor, constant: -stoplightMargin).active = true
        stopLightImageView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor, constant: 0).active = true
        stopLightImageView.heightAnchor.constraintEqualToAnchor(stopLightImageView.widthAnchor, multiplier: stoplightStartWidth/stoplightStartHeight).active = true

        self.view.addSubview(circleImageView)
        circleImageView.translatesAutoresizingMaskIntoConstraints = false

        //circle constraints
        circleImageView.widthAnchor.constraintEqualToAnchor(stopLightImageView.widthAnchor, multiplier: circleStartWidth/stoplightStartWidth).active = true
        circleImageView.heightAnchor.constraintEqualToAnchor(circleImageView.widthAnchor, multiplier: 1).active = true
        let stoplightWidth = screenWidth - 2*stoplightMargin
        let stoplightHeight = stoplightWidth * stoplightStartHeight/stoplightStartWidth
        circleImageView.leadingAnchor.constraintEqualToAnchor(stopLightImageView.leadingAnchor, constant: stoplightWidth*circleStartLeading/stoplightStartWidth).active = true
        circleImageView.topAnchor.constraintEqualToAnchor(stopLightImageView.topAnchor, constant: stoplightHeight*circleStartTop/stoplightStartHeight).active = true
    }
}

enter image description here

Upvotes: 1

KSigWyatt
KSigWyatt

Reputation: 1368

Constraints are tricky, and it looks like you have a lot going on there. It's hard to tell you exactly what to do for this so, here's what I would try to do if I was having this issue(hopefully one works for you):

  1. Set the images in the Attributes Inspector to either Aspect Fit or Redraw... That should fix your issue with them being different shapes.

  2. Also look through the list of constraints to see if one relies on another, (for example the red and yellow seem to have similar constraints). If they rely on each other, ensure to satisfy any constraints that aren't yet - based off of the "parent" image.

  3. Select everything and set to "Reset to Suggested Constraints". Build and run. If that doesn't fix it then there's only a few things left you can do.

  4. Remove all the constraints on every object. Start with the black image and add missing constraints... or set it to "Center Horizontally in Container". Right click and drag the image or asset to your "view" or to the yellow "First" circle located above. enter image description here

Hopefully this helps.

Upvotes: 1

Related Questions