Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorporating top layout guide #9

Closed
akashivskyy opened this issue Aug 21, 2013 · 7 comments
Closed

Incorporating top layout guide #9

akashivskyy opened this issue Aug 21, 2013 · 7 comments

Comments

@akashivskyy
Copy link

I am using a transparent UINavigationBar and UITextField. I want it to be 20px under the navigation bar, so I'm using the following commands:

[self.emailTextField mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo((self.view).mas_top).with.offset(20);
}];

However, my text field appears beneath the navigation bar, 20px from the top of the screen.

-- iOS 7 SPOILER ALERT --

In iOS 7 there is a topLayoutGuide property on UIViewController. How can I incorporate it using Masonry, so my text field appears under the navigation bar (84px from the top of the screen) both in iOS 7 with transparent navigation bar and in iOS 6?

I know that it can be done using NSLayoutConstraints. Taken from the documentation:

id topGuide = myViewController.topLayoutGuide;
// "button" is a UIButton object specified elsewhere
[myViewController.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-20-[button]"]];
@akashivskyy
Copy link
Author

I managed to do what I want using [viewController setEdgesForExtendedLayout:UIRectEdgeNone], but I'll leave this issue open as a feature request or at least to get an answer.

@cloudkite
Copy link
Contributor

At the moment topLayoutGuide and bottomLayoutGuide are not supported directly. However you could try using the length property of topLayoutGuide:

[self.emailTextField mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(self.view.mas_top).with.offset(self.topLayoutGuide.length + 20);
}];

if self.view is self.emailTextField's superview, then you could also write this as

[self.emailTextField mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(@(self.topLayoutGuide.length + 20));
}];

Let me know if that works for you

@akashivskyy
Copy link
Author

Yes, that kinda works, but I ended up by implementing my own version of those layout guides (for the sake of iOS 6 compatibility).

The problem with topLayoutGuide is that it is only correct when using only in several methods, but both examples that you provided work well.

@juri
Copy link

juri commented Feb 19, 2014

The problem with the .length workaround is that you often want a dynamic constraint. For example, if you have a view controller loaded from a XIB but want to add controls to the view, topLayoutGuide.length is 0 in -viewDidLoad and -viewWillAppear: but will go to 64 before viewDidAppear: if you are using a navigation bar. I usually want to add my subviews and their constraints before the view is on screen. Having direct support would be helpful.

@cloudkite
Copy link
Contributor

@juri a dynamic solution was found in this issue #27 thanks

@juri
Copy link

juri commented Feb 19, 2014

Oh excellent, thanks and sorry for the noise!

@Pratik-Sodha
Copy link

topLayoutGuide deprecated in iOS 11, Use view.safeAreaLayoutGuide.topAnchor instead of topLayoutGuide.bottomAnchor_

        txtLink.snp.makeConstraints { (make) in
            make.top.equalTo(self.view.safeAreaLayoutGuide).inset(20)
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants