0
votes

I'm creating a custom UIView called CTCycleClock with a subview called CTCycleSlider. It reacts to a gesture so it can rotate on one axis (like looking from above upon a roulette table).

To achieve this, the main view CTCycleClock creates two constraints on the CTCycleSlider subview that center it on X and Y.

Example:

enter image description here

Furthermore, the CTCycleSlider subview creates two constraints on itself that set a specific width and height. This is necessary because otherwise upon rotation, the disk will make itself larger.

This works nicely and correctly. But when the superview has a bigger size (for instance on iPad), I don't know how to tell AutoLayout that the subview has a new fixed width and height equal to the superview.

This is how I set constraints in the superview:

NSLayoutConstraint *centerX = [NSLayoutConstraint
                              constraintWithItem:subview
                              attribute:NSLayoutAttributeCenterX
                              relatedBy:NSLayoutRelationEqual
                              toItem:self
                              attribute:NSLayoutAttributeCenterX
                              multiplier:1.f constant:0.f];
NSLayoutConstraint *centerY = [NSLayoutConstraint
                               constraintWithItem:subview
                               attribute:NSLayoutAttributeCenterY
                               relatedBy:NSLayoutRelationEqual
                               toItem:self
                               attribute:NSLayoutAttributeCenterY
                               multiplier:1.f constant:0.f];

[self addConstraint:centerX];
[self addConstraint:centerY];

This is how I set constraints in the subview, where self.widthAndHeight is currently hardcoded to 320 on iPhone and 450 on iPad:

NSLayoutConstraint *w = [NSLayoutConstraint
                         constraintWithItem:self
                         attribute:NSLayoutAttributeWidth
                         relatedBy:NSLayoutRelationEqual
                         toItem:nil
                         attribute:NSLayoutAttributeWidth
                         multiplier:1.0f
                         constant:self.widthAndHeight];
NSLayoutConstraint *h = [NSLayoutConstraint
                         constraintWithItem:self
                         attribute:NSLayoutAttributeHeight
                         relatedBy:NSLayoutRelationEqual
                         toItem:nil
                         attribute:NSLayoutAttributeWidth
                         multiplier:1.0f
                         constant:self.widthAndHeight];

[self addConstraint:w];
[self addConstraint:h];

So my question is: how can I make a subview first hug the superview frame with a certain margin, but also set its width and height fixed?

EDIT: some clarifications as to why I need the constraint that sets width/height fixed.

When I won't set the width/height fixed, and the user touch-rotates the wheel, you get the following result:

wheel rotated but is made smaller because of missing width/height constraints

In the above image, I've set constraints on the subview that set top/lead/width/height to the superview. That works great when the user hasn't rotated the wheel subview yet, but when they do, the autolayout constraints force the rectangular UIView smaller so it completely fits in the superview.

Thus the question remains: how can I create constraints that initially resize the subview correctly to the superview, but then set a fixed width/height so upon rotation, it stays the same size?

1

1 Answers

0
votes

...how can I make a subview first hug the superview frame with a certain margin, but also set its width and height fixed?

I don't understand your question. If you make your image view hug the superview with a fixed margin (on all sides) then the size of the image view is dictated by the superview.

You could pin the image view on 2 sides (e.g. top and left) and specify a size. Then the distance to the other 2 sides would vary based on the size of the superview. Or you could center it in the superview and fix the size, and then ALL The margins would vary based on the size of the superview.