I add a TableView to a new Single View Application. The exercise requires me to allow the TableView control to fit the entire screen. But I can't find any function to do this. Should I adjust the parameters in the Table View in Size Inspector?
You really should learn auto-layout and constraints as they're an extremely important part of building up layout in UIKit.
For now, this is how you set your table view (or essentially any view) to fill the screen:
Select your table view
Click on the Add New Constraint button at the bottom right of your storyboard.
Set 0 for top, bottom, left and right.
That will add 4 constraints that will stretch your table view to fill up all the space available in the screen's safe area.
Related
I have to admit that I'm not a big fan of Auto Layout. But I guess I need to use it because of iPhone X.
Anyway, I have a simple layout. I have a map view (MKMapView) object and a view (UIView) object in pink at the bottom.
I have two layout requirements. (1) The top of the map view must sticks to the safe area. (2) The bottom of the pink view sticks to the superview.
First, I select iPhone X as a layout device.
As for the map view, I select the safe area and the map view and add align to top edges. I also add align to left edge and align to right edge. So I get the following.
As for the pink bottom view, I select the (super) view and the pink guy to add align to bottom edges. I then add align to the top, left and right edges. Also, the height is set to 48 pts. So I get the following.
Now, if I switch the layout device to iPhone 8 Plus, the layout will hold. But if I switch from iPhone X to iPhone SE, it will miserably break as shown below.
How can I maintain my layout regardless of devices? Thanks.
I can't completely replicate what your screenshots show; in particular I can't get the top level View to have the descendant constraint of "Bottom Space to Bottom View". I suspect you have some other constraints that are causing the conflict. I think it would be best to start over on this view controller to make sure you don't accidentally add constraints that don't belong.
Drag a Map Kit View and a View into this new controller, rename the View to "Bottom View" and add new constraints to the Map Kit View like this:
Then add the constraints for the Bottom View like this:
I have a view called wsview (whole screen view) inside my scene, covering the whole screen. Inside this view there is a scrollview (covering the whole wsview). Inside the scrollview I have a view (called viewgod) and viewgod is covering the whole scrollview. Inside viewgod I have some components (one under the other and each of them has constraints to the top and bottom component). Now I am trying to interleave another component (another view, called myview) between these components of viewgod.
When I add it, the scene does not resize in a way that myview will fit there the way I want; it overlaps with the other components. I defined the constraints so that I have top and bottom spacing to the components it is interleaved, but that does not solve the problem. I have also tried to resize the viewgod/wsview, but I can't resize them. I have also tried to resize the whole scene, and that kind of works, but I have to move the underlying components by hand and all of the constraints get messed up.
Is there a smarter way to do it or is there any way to do it at all?
storyboard ss
To "insert" a view between other views, while maintaining the rest of the layout, you need to delete the Vertical Spacing constraint between the "above" and "below" views, give yourself a little space, add your new view, then add vertical spacing constraints from the "above" view to the new view, and from the new view to the "below" view.
Hopefully, this will make sense:
Imagine your entire layout like this:
and you want to insert a new view between B and C.
Delete the constraint from B to C:
Select all the views from C to the bottom, and move them down to give yourself some space to work:
Now add your "new view", and move it / size it into position:
Re-adjust the position of the views below it:
and, finally, add new vertical spacing constraints from B to NewView and from NewView to C:
I've been having some problems centering text vertically beside an icon in a horizontal stack view. Here are some facts:
1) I create a view to hold stack view - add constraints
2) I place a horizontal stack view inside of that view - add width and height constraint, add vertically center constraint, add height constraint
3) Add an image and a label to the horizontal stack.
4) I make the image a certain width and match the height
5) I leave the label alone
6) I select the stack view and specify to set the Alignment to Center
In a new view controller this works great! Everything is perfectly aligned vertically. BUT in any existing controller I've created, it doesn't work! The text is rendered a few points above the center of the image, AND not at the top.
The only difference I can see is new view controller vs existing view controller, and simple layout compared to my more complex layout.
I have no auto layout errors, and don't really consider recreating all my view controllers to be an option. Anyone have any ideas?
Wow, so I have this partially figured out. Its the custom font we are using for our app!
This was the primary difference. All my normal app views inherit from a base view where I set the font for the entire view. That is why when I tested in new view controllers (not inheriting from base) it would work.
If you are having trouble getting text perfectly vertically centered and you think you have done everything right, check your font.
Happy coding...
I have a weird behavior when I use scrollView.
As you can see in the picture bellow the button called "Back" has a bottom space constraint with value 0. But we can see is not even near to the bottom of the scroll view.
I already set the scrollview to have equals width and height of the superView and top,bottom,trailing and leading space with 0 value.
How can I fix this? I want the Back button still inside of the scrollview and put it at the bottom of the view.
Update
I have the code here https://github.com/rchampa/NDParallaxIntroView and the xib is called PageB.xib
Ricardo: you've added two constraint regarding manage y position of Validate Code button where your top constraint stop to move Validate Code button towards the bottom. So please remove top constraint of Validate Code only add bottom constraint.
you need to manage all constraint like your scrollview content view height will be equal to height. Please increase some top constraint from top.
So, if I understand correctly, the problem you are running into is that your back button is unable to be positioned based on the bottom of the scroll view.
A scroll has two sets of constraints in a storyboard, one that defines the size of the scroll view, and the other that defines the content size. The top, left, bottom, right to superview constraints on the scroll view will define the size.
The part that is causing your problem is that the content size is defined by the subviews inside the scroll view. So the button cannot be placed relative to the bottom of the scroll view since the scroll view doesn't know how large its content size is. All of the subviews of a scroll view must be placed in relation to each other.
So, create constraints for your logo, text fields, and all the buttons in relation to each other. Then create constraints from the outer most subviews to the scroll view.
In your example, you would constraints from the logo to the text field, 1st text field to 2nd text field, then 2nd text flied to the label, label to the "Send email..." button, and finally "Send email..." to the "Validate Code". For the "Back" button, it would need a left align with the text fields and then a center align with the "Validate Code" button. Create a top constraint from the logo to the scroll view. Then have leading and trailing constraints from one of the text fields to the scroll view. Finally, create a bottom constraint from either the "Back" or "Validate Code" buttons to the scroll view. You will also need some alignment constraints (logo center to the text field is an example of one). After that is all setup, your view will be fully defined for the content size of the scroll view.
If I understand you, my new question is: how can I make the subviews
make the height of scroll fit 100% screen device height? Is there a
way to define weights like Android? I don't know how achieve this
since the canvas is 600*600 which is different to every device.
Response would be too long for a comment:
So you wouldn't use a scroll view for that. A scroll view is specifically for containing content that will not fit on the screen (so the user can scroll to reach the new content).
The simplest solution is to add a regular view that has TopLeftBottomRight 0 distance constraints (so it is the max height and width of the screen) and setup the view like you have here to position the bottom in the bottom left all the time.
There is also a weight system, I can explain that if you want, but it wouldn't be required thus far.
I feel like your next response will be something like "what if I want it to scroll when its too small for the current screen?". The only way I know of doing that in encapsulating all your interface into a single UIView, and changing its sized in the viewDidLoad/viewDidAppear based on the size of the scroll view. Something like this:
func viewDidLoad() {
super.viewDidLoad()
containerViewHeightConstraint.constant = scrollView.frame.size.height
containerViewWidthConstraint.constant = scrollView.frame.size.width
}
In an iOS 8 app, I'm trying to create a screen that has a "parallax header", i.e., an image header that grows as you pull down. I would like to do this using only constraints in Interface Builder, if possible.
Here is a nice guide by Pete Hare on how to do such a thing, and I've also had good help at looking at this example project by Bill Carson. However, contrary to these projects, this is not the header to a scrolling area that's taller than the screen, like a Table View; it's just one page. And for some reason, I can't get things to work in my app. I find Scroll Views in Interface Builder rather confusing to begin with. Could anyone walk me through the steps?
Why, certainly! First we'll set up a view controller with a scroll view.
Create an empty View Controller. Give its initial View the Xcode Specific Label Root View so we can tell things apart.
Add a Scroll View. Resize it to fill the view controller, and add constraints for Leading, Trailing, Top and Bottom to equal the superview's corresponding edges. (I do this by control-dragging from Scroll View to View in the Document Outline, hold down the Option and Shift key and then select all four edges, and then Add Constraints.)
Enable Bounce Vertically in the Scroll View's Attribute Inspector.
Add a simple View to the Scroll View and pin its edges to its superview -- the Scroll View -- in the exact same way as we did with the Scroll View to Root View (although this time we don't need to hold Option key when adding constraints). Give the new view the Xcode Specific Label Scrolling Content.
Xcode is not happy, it says Scroll View is missing constraints: "needs constraints for X position or width" and "needs constraints for Y position or height". Let it automatically add missing constraints, it will add constraints for the center of Scrolling Content to the center of Scroll View, in X and Y directions.
By setting a background color to the Scrolling Content, we can now run and confirm that the scroll view with vertical bounce is working as intended. Nice. Now, let's add the header.
Add a nice header image to the project assets, and drag an Image View to the Scrolling Content. Label it Header Image. Select your image asset as the Header Image's image. Drag the corners of the Image View so that it is aligned to the top, left and right edges of your view. Now let's go through the constraints to set on the Image View.
We want the top edge to be fixed to the top of the screen, regardless of how the user is scrolling. So we need it to be pinned to something outside of the Scroll View. You may try fixing it to the Root View's top edge, but unfortunately, that does not work for some reason. What does work is to pin it to the Top Layout Guide. You'll do this easiest by control-dragging in the Document Outline, between the Header Image and the Top Layout Guide and accpet the suggested constant.
The bottom edge of the Header Image needs to be pinned to something inside the Scroll View. Ultimately, we'd like it to be set to a fixed distance from the top of the Scrolling Content -- but Interface Builder won't let us do that. You can only set it to some distance from the bottom of the Scrolling Content, which is not very practical since you will then have to take the height of the device into account. What we instead do is to add another view directly beneath the Header Image, pin that view's top edge to some distance from the Scrolling Content's top edge, and then pin the Header Image's bottom edge to our new view's top edge. This could be a regular View that holds the rest of your user interface below the header. But for this example (and to demonstrate a later point in this guide), we'll use a label. Add a label directly beneath Header Image and give it three constraints: pin it's top edge to the Header Image's bottom edge, it's top edge also to the Scrolling Content's top edge, and it's center X to the Scrolling Content's center X. The distance between the label's top edge and Scrolling Content's top edge will be the height of the image in the non-dragged state. This unfortunately needs to be set to a constant in the storyboard file -- we'll have to update it programmatically. More on that later.
The last part is easy: pin the leading and trailing edges of the Header Image to the leading and trailing edges of the Scrolling Content.
Now, all our constraints are in place! If you run the app, you can see how it's working correctly constraintwise, but the image isn't scaling the way we expect it to. A couple of last tweaks before we're done.
In the Attribute Inspector, under View, set the Mode of the Image View to "Aspect Fill". That gives it the correct parallaxy behavior.
To set the height of the Header Image correctly, we need a little bit of code. First, make an outlet from the constraint between the label's top edge and the Scrolling Content's top edge -- the one we set to a fixed value -- to your View Controller's source file. Call it imageHeightConstraint. Also add an outlet from the Image View called headerImageView. A good place to update the constraint programmatically is in the viewWillLayoutSubviews View Controller delegate method. Here is some code in Objective C:
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
CGSize imageSize = self.headerImageView.image.size;
CGFloat heightForWidth = imageSize.height / imageSize.width;
CGRect screenBounds = [UIScreen mainScreen].bounds;
CGFloat screenWidth = CGRectGetWidth(screenBounds);
self.imageHeightConstraint.constant = screenWidth * heightForWidth;
}
Finally, you may notice that when scrolling up, the label -- or whatever content is underneath the header view -- is getting covered by it. This is solved by checking Clip Supbviews on the Image View's Attribute Inspector.
Whew!
(Note: I began writing this as a question and then kept writing while I solved it for myself. I guess it would do well with a little text pruning and some images, but maybe it will help someone...)