code

iPhone X에서 UIView의 safeAreaInsets가 0입니다.

codestyles 2021. 1. 10. 17:15
반응형

iPhone X에서 UIView의 safeAreaInsets가 0입니다.


내 앱을 iPhone X에 맞게 업데이트하고 있습니다. 하나를 제외하고는 모든보기가 정상적으로 작동합니다. 전체 화면을 다루는 사용자 지정 UIView를 제공하는 뷰 컨트롤러가 있습니다. UIScreen.main.bounds모든 레이아웃이 완료되기 전에 뷰의 크기를 알아 내기 위해 사용하기 전에 (collectionView에 대해 올바른 itemSize를 입력하기 위해 필요합니다). 이제 UIScreen.main.bounds.size.height - safeAreaInsets.bottom올바른 사용 가능한 크기를 얻는 것과 같은 일 할 수 있다고 생각 했습니다. 문제는 safeAreaInsets가 iPhone X (시뮬레이터)에서 시도하는 동안 (0,0,0,0)을 반환한다는 것입니다. 어떤 아이디어? 다른 뷰에서는 safeAreaInsets에 맞는 숫자를 얻습니다.

감사합니다!


최근에 viewDidLoad가 트리거 되 자마자 안전 영역 삽입이 (0, 0, 0, 0)을 반환하는 유사한 문제가 발생했습니다. 나머지 뷰 로딩보다 부분적으로 늦게 설정된 것 같습니다.

viewSafeAreaInsetsDidChange 를 재정의 하고 대신 내 레이아웃을 수행 하여 라운드했습니다 .

override func viewSafeAreaInsetsDidChange() {
 // ... your layout code here
} 

나는 이미 해결책을 알아 냈다. 나는 init뷰의 모든 구현을하고 있었다 . safeAreaInsets의 크기가layoutSubviews()


iPhone X의 키보드를 위해보기를 위로 이동하려고 시도하는이 문제도 발생했습니다.이 시점에서 하위보기가 화면으로 배치되었음을 알고 있지만 기본보기의 safeAreaInsets는 항상 0입니다. 그려졌습니다. 위에서 언급했듯이 내가 찾은 해결 방법은 keyWindow를 가져와 대신 안전 영역 삽입을 확인하는 것입니다.

Obj-C :

CGFloat bottomInset = [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom;

빠른:

let bottomInset = UIApplication.shared.keyWindow?.safeAreaInsets.bottom

그런 다음이 값을 사용하여 필요에 따라 제약 조건이나 뷰 프레임을 조정할 수 있습니다.


다른 뷰 내부의 하위 뷰인 뷰가 있습니다. 나는 safeAreaInsets를 올바르게 얻을 수 없다는 것을 알았습니다. layoutSubviews에 넣어도 iPhoneX의 해당 뷰에서 항상 0을 반환합니다. 마지막 해결책은 매력처럼 작동 할 수있는 safeAreaInsets를 감지하기 위해 다음 UIScreen 확장을 사용하는 것입니다.

extension UIScreen {

    func widthOfSafeArea() -> CGFloat {

        guard let rootView = UIApplication.shared.keyWindow else { return 0 }

        if #available(iOS 11.0, *) {

            let leftInset = rootView.safeAreaInsets.left

            let rightInset = rootView.safeAreaInsets.right

            return rootView.bounds.width - leftInset - rightInset

        } else {

            return rootView.bounds.width

        }

    }

    func heightOfSafeArea() -> CGFloat {

        guard let rootView = UIApplication.shared.keyWindow else { return 0 }

        if #available(iOS 11.0, *) {

            let topInset = rootView.safeAreaInsets.top

            let bottomInset = rootView.safeAreaInsets.bottom

            return rootView.bounds.height - topInset - bottomInset

        } else {

            return rootView.bounds.height

        }

    }

}

컨테이너 뷰 컨트롤러의 viewDidAppear (_ :) 메서드는 포함 된 자식 뷰 컨트롤러의 안전 영역을 확장하여.

보기에 대한 안전 영역 삽입은보기가보기 계층 구조에 추가 될 때까지 정확하지 않기 때문에이 방법을 수정하십시오.

override func viewDidAppear(_ animated: Bool) {

   if (@available(iOS 11, *)) {

     var newSafeArea = view.safeAreaInsets

     // Adjust the safe area to accommodate 
     //  the width of the side view.

     if let sideViewWidth = sideView?.bounds.size.width {
        newSafeArea.right += sideViewWidth
     }

    // Adjust the safe area to accommodate 
    //  the height of the bottom view.
    if let bottomViewHeight = bottomView?.bounds.size.height {
       newSafeArea.bottom += bottomViewHeight
    }

    // Adjust the safe area insets of the 
    //  embedded child view controller.
    let child = self.childViewControllers[0]
    child.additionalSafeAreaInsets = newSafeArea
  } 
}

I've come across the same problem. In my case the view I'm inserting would be sized correctly after calling view.layoutIfNeeded(). The view.safeAreaInsets was set after this, but only the top value was correct. The bottom value was still 0 (this on an iPhone X).

While trying to figure out at what point the safeAreaInsets are set correctly, I've added a breakpoint on the view's safeAreaInsetsDidChange() method. This was being called multiple times, but only when I saw CALayer.layoutSublayers() in the backtrace the value had been set correctly.

So I've replaced view.layoutIfNeeded() by the CALayer's counterpart view.layer.layoutIfNeeded(), which resulted in the safeAreaInsets to be set correctly right away, thus solving my problem.

TL;DR

Replace

view.layoutIfNeeded()

by

view.layer.layoutIfNeeded()

[UIApplication sharedApplication].keyWindow.safeAreaInsets return none zero

Just try self.view.safeAreaInsets instead of UIApplication.shared.keyWindow?.safeAreaInsets Safe area insets seems to not fill on iOS 11.x.x devices when requested via application keyWindow.

ReferenceURL : https://stackoverflow.com/questions/47032855/safeareainsets-in-uiview-is-0-on-an-iphone-x

반응형