iOS 6 Constraints Making the UIView Longer - ios

I am not sure what is going on and how to handle this. I have a UIView in a cell and I set the constraints using IB and for some reason it stretches out to the end of the cell. How can I stop it from stretching.
And here is the result:
I am dynamically injecting a stepper control but as you can see the UIView stretches to the end of the cell. I tried pin width then it completely messes up everything and does not even display the UIView.
Here is the screenshot of constraints:

Okay, let me draw some distinctions here.
The trivial way to this is you always have the stepper in the cell (and no UIView). For those cells where we are not supposed to see the stepper, you set its hidden to YES; for those cells where we are supposed to see it, you set its hidden to NO. That is what I would do.
The programmer way to do this is you don't have any blue UIView in your cell at all. You add the stepper in code, and you also provide its constraints in code to position it. You said:
so I don't have to hardcode the coordinates
But adding constraints in code is not "hard coding" the coordinates. With constraints, you describe the position conceptually in terms of insets from the superview, and as the superview resizes, you are still correctly positioned. So there is no philosophical objection to adding the stepper and its constraints, and it is just laziness not to do that.
The lazy but wasteful way is to do what you are doing, i.e. add the blue UIView in the nib as a guide. Even if you do use the blue UIView as a guide, though, you should be able to get this right if your constraints are right. I just tried this and I was not able to reproduce the problem: my blue view appeared in my cells in the same place where it appears in Interface Builder.
The instant solution is don't use Autolayout in the nib from which a UITableViewCell is drawn — i.e. uncheck "Use autolayout" in the file inspector for this nib. You will thus use old-fashioned springs-and-struts (autoresizing) to position the subviews.

Related

Adjusting Subclassed UITableViewCell UILabel Frame

I have a subclass UITableViewCell. In storyboard I added some labels and buttons and created respective outlets, and I set and tweaked their respective frames using the size inspector. The layout looks good for a iPhone 6. On an iPhone 5 things are off screen on the right. In the layoutSubviews method of the UITableView subclass I attempt to adjust the frame of my labels and buttons. When the tableview first appears the buttons and labels are in the positions specified for their respective frames in Storyboard and not in the frame/position I set in layoutSubviews. A moment later they appear in the positions set in layoutSubviews. Sometimes however, I see it revert to the old storyboard set position.
Any ideas what might be happening? I want to set the labels and button frames explicitly and have them stay where I put them. I don't want to use constraints as they are really painful to use in Storyboard, and frequently don't behave well or with good granularity.
If you do not use constraints, please remove use auto lay out and use size class.

UIView added with autolayout does not receive taps/events

When I add a subview with autolayout by settings its left, right, top, and height constraints, I cannot add a tap gesture and my buttons do not receive taps.
When I manually set the frame to the position I need and do not use autolayout, I can add gesture recognizers and my buttons are interactive.
Why would a view added with autolayout not respond to events?
I would like to use autolayout since I would like to respond to different orientations and sizes that are more complex than I would like to deal with with manual frame adjustment.
This can happen if you have restricted your view too much using autolayout. For example, you may have accidentally set the height of the view to zero or positioned it outside the area where you put your buttons. Note that the buttons themselves can be positioned in a place that appears correct when you look at them, but they are actually outside the area that the autolayout engine has calculated for the parent view.
Another thing that can hit you, is that if you added all your autolayout contraints programmatically, some contraints in the Interface Builder may still be enabled. You can make sure that IB contraints are ignored by setting view.translatesAutoresizingMaskIntoConstraints = NO;
Also, pay attention to any runtime autolayout warnings in the console window, they will often tell you if some contraints don't play well together.

Why isn't this UIScrollView autolayout working?

I have a simple program with a UIScrollView, and one UITextField inside it. I constrain the UIScrollView to have 0 space on all it's four sides, which I thought would make it fill the screen. And I constrain the text field to be the standard space from the edges:
But when it runs, it does this:
I see the technical note, but I don't understand it yet.
The field will fill the screen if I give a width=280 constraint, but that goes against the spirit of autolayout. I want it to adapt to the width of the screen, not be hard coded to the 280pt width in the storyboard. How to do that?
Here are the layout errors:
I found an answer to my own question.
The answer is contained in the tech note, but in my opinion not explained in enough detail. This blog post helped me: http://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/
Summary: put a width constraint on the text field to shut up the IB errors, but then check the "Placeholder, remove at build time" checkbox for the constraint (in the attribute inspector in IB). Then you can add better constraints programmatically, in the view controller's viewDidLoad method. In this case I want constraints that connect the text field's left and right edges to the scroll view's superview edges (and thus the screen edges). You apparently can't make constraints like this in IB. With those two constraints, it all works correctly, even as the screen is rotated.

Why does UIButton resize when I access titleLabel property?

I'm trying to adjust the size of a button to (it's intrinsic size + a little bit more) in order to draw a custom background. However, every time I access self.titleLabel within the button, the size and position resnaps to that of the storyboard. I don't have to do anything with the label to reproduce this, just retrieve it from the button.
I've put logging code all over my button and view controller in order to find where this is happening. It's not coming from a relaying-out of subviews or any other notification I see to get within the view controller. The line before accessing titleLabel, the position and size are correct. The line after, it has snapped back to the storyboard position. Commenting out the access prevents the size/position snapping. Can someone tell me where or why this is happening?
I have no constraints set (that I can tell), but am I fighting against auto-layout here? Should I be doing this a different way like composing controls or something?
Something similar (or the same?) has been asked before at UIButton modifying titlelabel seems to change its frame and UIButton titleLabel resizes on press?, but both were left unanswered or explained away with just "maybe a bug."
If the project has auto-layout enabled, then YES, you're fighting auto-layout. You have two choices, either subclass UIButton so that you can override the intrinsic size calculation, or modify the constraints so that the intrinsic size is not used in any constraint. If you do the latter, then you probably want to create an IBOutlet to the constraint for the width, so that you can adjust the constant property as needed.
This isn't a bug, it's a consequence of auto layout. When using auto layout, you shouldn't set any frames. Instead, you should change the size or position by modifying the constraints. What's happening, is that whenever the view needs to be redrawn, the frame reverts to the frame that's defined by the constraints.

Set UIView height based on inner view height using constraints

I have one UIView and inside that, N UILabels which are laid out relative to each other.
The containing UIView has a background color, I want to extend the UIView to be high enough to cover all labels inside it, so the background color is behind them all.
(I'm embedding them in a UIView so I can have the labels inset from the view edges.)
Is there away to make the UIView's height expand to fill its content? I can't figure it from the constraint options, it seems like its all relative to superviews.
Normally I'd just work out the frame sizes programatically in viewDidAppear but those are getting reset by the constraints system, AFAIK.
I think I actually worked it out though.
I had the labels height set manually from when I drag-dropped and resized it. Deleting the height constraint on the UILabel made it size to fit content, which causes its superview to resize too. At least I think that's the case, I'm new to constraints.
Will leave the question up since it will probably bite someone else too.

Resources