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.
Related
I have been trying to get ScrollView to work for 2 days now, and it doesn't work at all. Most of the suggestions here on SO and other websites say that you need to pin the ScrollView to the root view and then place a ContentView (UIView) inside ScrollView and then pin it to all sides of the ScrollView (so that the scroll size can determine the contentSize... However this does nothing). There's also conflicting information out there, one video says that there needs to be a constraint from the bottom of the ScrollView to the ContentView. Neither solution has worked for me. Here is what I've been doing in most of the combinations I've tried:
UIView -> UIScrollView
Pin all sides of the UIScrollView to the UIView
Create a UIView (name it content view) and place it inside UIScrollView
Pin all sides of the UIView to the UIScrollView
Problem at this point: UIScrollView needs constraints for X or width AND Y or width. The only thing that seems to solve the complaint is setting the UIView inside the scroll view centered horizontally and vertically, but this does nothing to make scrolling work. Another option is setting the UIView equal height and width to scroll view, but again, that does nothing other than remove the complaint.
I don't understand. Isn't pinning the sides, setting the constraints? IB seems to think that this is not the case.
What are the correct constraints needed? All I need is a simple view with stacked controls (to fill out a form) and the screen needs to be able to scroll if the form is longer than the screen.
I'm using iOS for the first time, and building purely from IB for now... minimal code solution would be best.
You are half way there. First you need to decide what you are going to display in the scrollview, you have placed a content view, that needs to have an intrinsic size. You can choose to put there static or dynamic views. Static views will have their size defined at design time, and that will resolve the UIScrollView AutoLayout constraints. If instead you are doing it at runtime with dynamic views you will need to choose a default size for your content view, create an IBOutlet for the width and/or height of your views and then resize them at runtime altering the outlet in viewDidLayoutSubviews. The video you linked explains that quite clearly.
I am learning constraints and spent whole day applying them to the following screen.It is not getting displayed properly in landscape mode.Basically i am not getting how to fix vertical space between ,say, label-Welcome to BBBB and textfield-username so that textfield always appears below the label yet the spacing between them is adjusted according to the screens of different size. If i go for Pin\Vertical space, it automatically fixes the constant value.
Remove the label (or just move it out of the way).
Fill the space that you want to resize with a view.
Constrain this view to the objects above and below and to the sides of the parent view.
Put your label into this view and constrain it to the top of this view and centred to it.
You may need to change the constraints on the objects above and below it to stop them from changing height in an unwanted manner.
This new view should now resize as the device changes orientation but the label should remain at the top of it.
Repeat on other areas of your layout (i.e put things that are not moving around as you want them into sub views and constrain these views to resize accordingly). Experiment with using variable heights, fixed heigh constraints and 'equal heights with' constraints on the views that you add to get them to resize as you need.
Edit: but you have a lot of vertically stacked items in that view - you may never get them all to fit into a horizontal orientation. You may need to remove a few, or add a scroll view or force that view only to layout in portrait mode or... Don't forget to check that it works on all devices you are targeting.
#Ali Beadle was right. Since i had a lot of vertically stacked items, lining them up in landscape mode was not possible. So, i went for scrollview.
I have taken a ScrollView first and then a UIView named ContentView on that ScrollView. I have made the width of ContentView equal to the width of parent UIView and kept its height fixed to 568. In my code i set
_contentViewHeight.constant = self.view.frame.size.height;
Now it scrolls in landscape mode while in potrait mode, it does'nt scroll.
I run into Autolayout problems all the time. But I finally figured out a way to overcome a lot of issues that arise from it.
I simply will use a container-View like ScrollView or even a plain old UIView, place all my controls in it. thats it. this makes things a lot easier for autolayout to figure out the constraints. in your case you could just use a UIView.
-start off by removing all the constraints you have I would start by selecting each control in the XIB and see if it has width/height constraint, select it then press the delete key then at the bottom of the project explorer you'll see all the constraints that auto layout has select each one then delete. that should get rid of any complaints that auto-layout might have.
-Place a UIView object inside your main View then
-move all the controls inside it. Then
-add the necessary constraints for the container view so it'll resize in different orientations and don't worry about any constraints inside the container view (auto layout will figure them out automatically).
that does the trick for me usually.
This seems like it should be very simple, but I am having a terrible time trying to get every subview (they act like menu bars) constrained to the bottom of the parent view in the IOS storyboard.
There seems to be automatic constraints placed between the subviews that make them override the constraint I'm trying to set. I try to take these off, and then place the new constraints, but nothing seem to work as I loop over trying to reset constraints, over and over and over...
It should be very simple, set all of the uiviews to a particular width and length and set the distance between the bottom of the superview to be equal to 0. That's it.
The secret to happy constraint editing in interface builder is simple:
Don't do it
If that isn't possible, then:
Create your own constraints before trying to delete the system ones
Make judicious use of the pinning menu and editing constraints in the inspector
Don't drag and drop your views after you've added them - this causes interface builder to discard all constraints and set you up with a new set of "best guess" system constraints.
I've written more about this here but that's the gist of it.
I have a UITextView set in my storyboard at a certain position. When the app first loads up, I would like the textView to be at a different position then where it is in the storyboard. I do this programmatically by setting its frame to a different frame with a different origin (later the textView will be animated back to the original position). But no matter how I do it, the app always starts up with the textView in its storyboard assigned position. I can't seem to do this anywhere... viewDidLoad:, viewWillAppear:, nothing works. How can I override it?
One other thing... lets say the textView has a different origin then it does in its storyboard (the frame was reset at some point in the app). If I add a subview to the textview using addSubView:, the textView resets to its original position in the storyboard. Why?! Any way to stop this?
If you want to change the position of the textView when it starts up, I'd suggest that you do not have it in the storyboard and instead add it to the subview with its correct frame.
Especially with Autolayout in effect, having it there already means you would have to modify its constraints and if you're modifying its position programmatically already anyway, you might as well add it to the view programmatically too where you have more control over its constraints programmatically as well.
Under auto layout you can't set frames - well, you can, but as soon as another layout pass takes place, the frame will be reset to that defined by the constraints.
The simplest way to change the size or position of views you've laid out in interface builder using auto layout is to create outlets to the various constraints, and then edit their constant properties. If that doesn't give you enough flexibility, you still need outlets to the constraints, but when you want to move things you'll have to delete those constraints and add new ones.
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.