iOS 7 Auto Layout - Ignore In-Call Status Bar - objective-c

Using Auto Layout constraints, I am trying to set up a subview with a vertical position that never changes, even when the in-call status bar (or some other non-standard status bar) is showing. I don't want to position the view relative to the Bottom Layout Guide because I want its y-coordinate to be the same for 3.5" and 4" devices.
Here's an illustration of what I want to have happen:
Initially, I set up the subview with a "Top Space to: Top Layout Guide" constraint for its y-position. With this configuration, the In-Call Status Bar pushed the subview 20px downward:
Next, I tried replacing that constraint with "Top Space to: Superview," where Superview was the root view of the controller. No change. Is there some other way to maintain a constant y-position for a view with Auto Layout constraints? I know I could resort to handling this manually by subscribing to UIApplicationDidChangeStatusBarFrameNotification, but I'd like to keep things simple if I can.

Your label is positioned to have a margin on top, between the start of the view and the start of the label. When the status bar grows, your view is shrunk. If you wish the label to remain in the same place, you can listen to UIApplicationWillChangeStatusBarFrameNotification notifications and adjust your view's size and origin to offset the additional space of the status bar. If you only want your label to shift up, you can also listen to the notification above, and adjust the top space constraint accordingly.

No you cannot.
The frame looses 20 px height in Portrait :( and the layoutguides don't care about it.
So either you do what Leo Natan said and use the notifications UIApplicationWillChangeStatusBarFrameNotification
Or either you will have to use the bottomConstraint as you dont want to do.

Related

Sub View with 50% height of the space left between navigation bar & tabbar

I don't want to do this programatically. Please show me the storyboard way to achieve this.
I want orang view to of half size of the space between nav-bar & tabbar. Refere dashed rect, I want half of that rect.
There are a couple of ways to approach this that I can think of.
Use a container view
The first is to add a UIView to the superView to act as a container. You can "pin" this container view to the bottom of the navigation bar and the top of the tab bar.
Now add your orange view to this container. With constraints pinning it to the top, left and right. You can then give it equal height with the container and a 0.5 multiplier and it will have half the height between the nav bar and tab bar.
Use a "spacer" view
The other method is to use a spacer view. Add your orange view and then add another view beneath it. Pin them to the nav bar and tab bar respectively and give them a vertical spacing of 0 between them.
Now give them equal heights.
This will make them both take up half the space between the nav bar and the tab bar.
Now make the "spacer view" hidden. It will hide but the constraints will still work.
Both of these will work for any device size and any orientation. Also, for edge cases like if satnav guidance or an incoming call changes the height of the nav bar etc...
As #Fogmeister mentioned You can use spacer view
Pin both of them and make their heights Equal Height.
And set blue view Hidden.
Very easy, add the following constraints.
Left and right constraints pinning the view to the superview.
Top constraint pinning view to superview with a constant of 64 to offset the nav bar.
Equal heights constraint with the superview. Change the multiplier of this constraint to 0.5 and the constant to -54 (half of the 64pt nav bar + status bar and half of the 44pt tab bar) and update frames.
Job done. :)

Is there a way to shrink a constraint with autolayout without code?

Without using code, I'm basically trying to achieve the "Desired outcome" in this picture:
I want the constraint on the "Hello!" label to shrink its length when the screen height is shorter.
As you can see in "Actual result", the Button in the bottom is off the screen. I want the image view to have fixed width and height.
I know I can create IBOutlets for constraints and doing it by code like this kind of posts suggest (autolayout - make height of view relative to half superview height), but I'm trying to avoid using code as much as possible.
Side question: If there's no way to do this in IB, what are the best ways to do this in code?
Thanks for the help!
Yes. The easiest way to have this kind of "split height" constraint is to put a "header" view between your image view and the top of the screen, and embed your "Hello" label inside this new header view. Then add a constraint to keep the "Hello" label vertically centered inside the header view.
To keep the header view the right size, add constraints to keep the top of the header view pinned to the top of the screen, and the bottom of the header view to the top of the image view.
Then you'll just add constraints to keep the button and image view pinned to the bottom of the screen. (Or, see comment from Sulthan, below.)
In Xcode 5.1 (in beta), there is UI to make more general constraints, including the ones you want, but you have to do it like this or in code in earlier versions.

UIToolbar not resizing when rotating with autolayout, with UIBarButtonItems misplaced

it's the first time I'm seriously using autolayout so I'm sure I'm missing something obvious.
I have a very simple view embedded in a UINavigationController. There are three subviews: a UIWebView, a UIToolbar (which in turn contains three UIBarButtons) and a UIActivityIndicatorView. It's just a basic browser view, basically.
I managed to have everything appear as it should even on rotation, except for the toolbar: if the view is first loaded in vertical orientation, going landscape will not resize the toolbar from 44 to 32 points. Originally, before I wiped everything out, it did resize the toolbar BUT the built-in UIBarButtonItems appeared lower and cut off, as if the toolbar was still 44 points tall but pushed 16 points out of the screen.
If the view is first loaded horizonttaly, the bar is 32 points high but the built-in UIBarButtonItems appear still like that, and rotating to vertical will keep it at 32 points.
I honestly have no idea how to make this work as expected (ie. resize properly when rotated, with the buttons showing properly!), so if anyone could point me in the right direction -- pun intended -- I would be really grateful.
The activity indicator is right in the middle of the frame, with these constraints:
Align Center X to Superview
Align Center Y to Superview
The web view is set to use all available space from the top of the view (including the navbar) up to the top of the toolbar, and has these contraints:
Top Space to Superview
Bottom Space to Toolbar
Align Trailing to Toolbar
Bottom Space to Toolbar (it's actually listed twice)
Align Leading to Toolbar
The toolbar is a mess. It has:
Bottom space to Superview
Align Center X to Superview
Top Space to Web View
Align Trailing to Web View
Top Space to Web View (listed twice)
Leading Space to Superview
Align Leading to Web View
Bottom Space to Bottom Layout Guide
The problem is that by not adding any constraints at all, the web view is much bigger than it should be, and the toolbar doesn't even show.
I mostly set these constraints using the horizontal and vertical red bars (similar to springs and strouts) in the 'pin' popover for autolayout, but I'm starting to think that's not the most appropriate approach.
Note that I'm not trying to use autolayout within the toolbar, I read that it wouldn't work and I'm just using the built-in buttons plus a couple of labelled ones (those 'arrows' are really unicode characters, I may change them to prettier images at some point.)
Thank you in advance. :-)

How to align the bottom of a UIView with the bottom of the screen always

I want a background image to always be aligned with the bottom of the screen regardless of screen size, iOS Version, or Personal Hotspot messages etc. But none of the interface builder alignment options seem to work in every case.
I have 2 different sized images to fit 3.5' and 4' retina which change via code but their alignment is always thrown off by 'Personal Hotspot' and other messages changing the size of the parent view.
My images are the size of the screen and should fill the whole screen always. There is a black area where tab bar and status bar will overlay.
There are buttons aligned with the background and everything gets thrown out by messages that resize the parent view.
I want the bottom of the UIImageView to be aligned with the bottom of the screen always.
have you tried the contentMode property?
theImageView.contentMode = UIViewContentModeBottom;
There is also a menu item for this in interface builder if you prefer to set it there.
then if you are using auto layout, simply add a bottom space constraint from your image view to the bottom layout guide.
If you're not using auto layout, a fixed bottom margin on the autoresizing mask should do the trick.

dynamically load UICollectionView in xcode

We have a label followed by a UIViewCollection. The height of the label is dynamically set based on its content. Based on the height of the label, we want to start the UIViewCollection as soon as the label ends. We are tracking the label x, y, width and height and adding some padding to y in the code to calculate the start of UIViewCollection. However, UIViewCollection does not move at all. Is it because of the specified storyboard? We tried it in ViewDidLoad and ViewWillAppear.
Also, if we replace the UIViewCollection with a label such that there are 2 labels one below another, we are able to dynamically load the start of the 2nd label if the code is placed in ViewWillAppear.
Please can someone help with moving the UIViewCollection up or down based on the previous label height?
Thanks in advance.
It may be because You use autolayout. You can switch off autolayout or set translatesAutoresizingMaskIntoConstraints YES for UIViewCollection, and than set current location
If you're using auto layout this is easy to do, and you don't need to do anything in code to keep track of the label's height. The label should have a height constraint to the top of the view and a spacing constraint to the top of the collection view (the length of that constraint will give you whatever padding you want between them). The collection view then needs a constraint to the bottom of the view. This setup will cause the collection view to get shorter when the label gets taller. If instead, you want the height of the collection view to stay the same, but move down (assuming that it's short enough that there's room to move down), give the collection view a fixed height constraint, and remove its constraint to the bottom of the view.