Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe area not work properly on iPhone X when subviews are not in the view area

I have a scrollView contains 2 child viewController. You can see VC2 not layout properly.

I found if view is not yet visible onscreen. safeAreaInsets is always 0.

I can call vc2.view.setNeedsLayout() to fix this problem when scroll ended. But the layout is not correct until scroll ended.

The document says

If the view is not currently installed in a view hierarchy, or is not yet visible onscreen, the edge insets in this property are 0.

So how can I fix this situation.

enter image description here

Autolayout enter image description here enter image description here

like image 202
PowHu Avatar asked Sep 18 '17 03:09

PowHu


People also ask

What is a safe area iOS?

The safe area represents the portion of your screen that is unobscured by bars and other operating system based content. Safe area is pre-defined by iOS across all Apple devices and is present in Android devices as well.

How do I remove safe area?

You can disable safe area layout guide from storyboard for particular view controller. Select View Controller -> File Inspector (first tab) -> Use safe area layout guides (uncheck the checkbox). You can also change it programmatically in viewDidLoad(). Hope this Helps!

How do I add a safe area in Xcode?

To use the new safe area, select Safe Area Layout Guides in the File inspector for the view controller, and then add constraints between your content and the new safe area anchors. This prevents your content from being obscured by top and bottom bars, and by the overscan region on tvOS.

What is Safearea Swift?

A safe area defines the area within a view that isn't covered by a navigation bar, tab bar, toolbar, or other views. SwiftUI views respect safe areas out of the box. But there are plenty of situations when you need to customize this behavior.


2 Answers

instead of referencing the current view's safeAreaInsets, set it to the UIApplication:

(UIApplication.shared.delegate?.window??.safeAreaInsets.bottom)
like image 52
ajayb Avatar answered Oct 07 '22 22:10

ajayb


In your child view controllers if you set the view controllers additionalSafeAreaInsets equal to the window's safe area insets they will layout correctly respecting the safe areas.

I found I had to do this inside of viewDidLoad() and viewWillTransition(to size: CGSize, with coordinator: UIVIewControllerTransitionCoordinator

Inside of viewWillTransition you will want to set the additionalSafeAreaInsets in the animation block of the coordinator:

coordinator.animate(alongsideTransition: { _ in
    if #available(iOS 11.0, *) {
        self.additionalSafeAreaInsets = UIApplication.shared.delegate?.window??.safeAreaInsets
    }
}, completion: nil)
like image 20
Kylelol Avatar answered Oct 08 '22 00:10

Kylelol