Reputation: 2072
In my iOS app, I have views rendered beneath the navigation bar. This is because the navigation bar is hidden until the user taps the screen.
The screenshots below illustrate my problem.
The "X" button is rendered beneath the iPhone X's notch and can hardly be seen. This is when I constrain the button's topAnchor
to its superview!.topAnchor
.
Note that this works as intended for all devices except the iPhone X.
The "X" button in this screenshot is anchored to its superview!.safeAreaLayoutGuide.topAnchor
and renders below the navigation bar. This makes sense given Apple's documentation on safeAreaLayoutGuide
:
"this guide reflects the portion of the view that is not covered by navigation bars, tab bars, toolbars, and other ancestor views."
However, I want the "X" button to render below the iPhone X's notch and underneath the navigation bar. Here's what it looks like when the navigation bar is hidden:
The "X" button should render right below the notch.
So my question is:
Is there a way to exclude the navigation bar from a view's safeAreaLayoutGuide
? And if not, what are my options, other than manually offsetting the button on iPhone X's.
Note that I'm doing everything programmatically. I no longer use Storyboards.
Thanks!
Upvotes: 9
Views: 4954
Reputation: 31
You can change the view controllers safe area insets by adding additional insets.
Create a UIEdgeInsetsMake()
object where you subtract the navigation bar height from the top inset. Then add it to the View Controllers additionalSafeAreaInsets
.
Declaration: var additionalSafeAreaInsets: UIEdgeInsets { get set }
Upvotes: 3
Reputation: 2072
This is not an answer, but a workaround:
layoutSubviews()
, update the constant of the top constraint depending on the "X"'s superview and window safeAreaInsets
.override func layoutSubviews() {
// To support devices with a "safe area". If the receiver has a top safe area, position
// the close button beneath the _window's_ safe area.
// Note that using the receiver's safe area does not work in this case because it includes
// the navigation bar. We want to render the close button beneath the navigation bar.
let windowSafeAreaInsets = UIApplication.shared.keyWindow!.safeAreaInsets
// Only use the safe area if the receiver _and_ window have a top safe area. This handles
// the case of non-safe area devices using a hidden navigation bar.
closeButtonTopConstraint.constant = safeAreaInsets.top > 0 && windowSafeAreaInsets != .zero
? windowSafeAreaInsets.top : 16
// Possibly do something similar for landscape and the "X" button's trailing constraint.
}
Upvotes: -1