[ios] 안전한 지역 삽입 상하 높이 확보

새로운 iPhone X에서 안전하지 않은 지역의 상단 및 하단 높이를 얻는 가장 적절한 방법은 무엇입니까?

여기에 이미지 설명을 입력하십시오



답변

이 시도 :

에서 목표 C

if (@available(iOS 11.0, *)) {
    UIWindow *window = UIApplication.sharedApplication.keyWindow;
    CGFloat topPadding = window.safeAreaInsets.top;
    CGFloat bottomPadding = window.safeAreaInsets.bottom;
}

에서 스위프트

if #available(iOS 11.0, *) {
    let window = UIApplication.shared.keyWindow
    let topPadding = window?.safeAreaInsets.top
    let bottomPadding = window?.safeAreaInsets.bottom
}


답변

레이아웃 가이드 사이의 높이를 얻으려면 방금 수행하십시오.

let guide = view.safeAreaLayoutGuide
let height = guide.layoutFrame.size.height

그래서 full frame height = 812.0,safe area height = 734.0

아래는 녹색 뷰의 프레임이있는 예입니다 guide.layoutFrame

여기에 이미지 설명을 입력하십시오


답변

스위프트 4, 5

제약 조건을 사용하여 뷰를 안전 영역 앵커에 고정하는 것은 뷰 컨트롤러의 수명주기에서 API에 의해 큐에 대기되고 뷰가 메모리에로드 된 후에 처리되기 때문에 어디서나 수행 할 수 있습니다. 그러나 안전 영역 값을 얻으려면 다음과 같이 뷰 컨트롤러의 수명주기가 끝날 때까지 기다려야합니다 viewDidLayoutSubviews().

이것은 모든 뷰 컨트롤러에 연결됩니다.

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let topSafeArea: CGFloat
    let bottomSafeArea: CGFloat

    if #available(iOS 11.0, *) {
        topSafeArea = view.safeAreaInsets.top
        bottomSafeArea = view.safeAreaInsets.bottom
    } else {
        topSafeArea = topLayoutGuide.length
        bottomSafeArea = bottomLayoutGuide.length
    }

    // safe area values are now available to use
}

API가 디자인 된 방식이므로 장치 방향 변경과 같은 모든보기 변경 중에 값이 업데이트되므로 가능한 한이 방법을 사용하는 것이 좋습니다.

그러나 일부 사용자 지정 제시 뷰 컨트롤러는 위의 방법을 사용할 수 없습니다 (일시적인 컨테이너 뷰에 있기 때문에 의심됩니다). 이러한 경우 루트 뷰 컨트롤러에서 값을 가져올 수 있으며, 현재 뷰 컨트롤러의 수명주기에서 언제 어디서나 사용할 수 있습니다.

anyLifecycleMethod()
    guard let root = UIApplication.shared.keyWindow?.rootViewController else {
        return
    }
    let topSafeArea: CGFloat
    let bottomSafeArea: CGFloat

    if #available(iOS 11.0, *) {
        topSafeArea = root.view.safeAreaInsets.top
        bottomSafeArea = root.view.safeAreaInsets.bottom
    } else {
        topSafeArea = root.topLayoutGuide.length
        bottomSafeArea = root.bottomLayoutGuide.length
    }

    // safe area values are now available to use
}


답변

여기에 다른 답변은 없었지만 이것은 효과가 없었습니다.

var topSafeAreaHeight: CGFloat = 0
var bottomSafeAreaHeight: CGFloat = 0

  if #available(iOS 11.0, *) {
    let window = UIApplication.shared.windows[0]
    let safeFrame = window.safeAreaLayoutGuide.layoutFrame
    topSafeAreaHeight = safeFrame.minY
    bottomSafeAreaHeight = window.frame.maxY - safeFrame.maxY
  }


답변

도움을 주신 모든 분들께 감사드립니다.

그러나 안전 영역 주제가 약간 혼란스러워서 잘 문서화되지 않은 것으로 보입니다.

내가 여기를 요약 있도록 가능한 한 박쥐 우산으로 쉽게 이해할 수 있도록하기 위해 safeAreaInsets, safeAreaLayoutGuide그리고 LayoutGuide.

iOS 7에서 Apple은의 topLayoutGuidebottomLayoutGuide속성을 소개했습니다 UIViewController. 상태, 탐색 또는 탭 막대와 같은 UIKit 막대에 의해 콘텐츠가 숨겨지지 않도록하는 제약 조건을 만들 수 있습니다 상단 또는 하단 탐색 요소 (UIKit 표시 줄, 상태 표시 줄, 탐색 또는 탭 표시 줄…)에 의해 숨겨집니다.

예를 들어 tableView를 시작 화면에서 시작하려면 다음과 같이하십시오.

self.tableView.contentInset = UIEdgeInsets(top: -self.topLayoutGuide.length, left: 0, bottom: 0, right: 0)

iOS 11에서 Apple은 이러한 속성을 더 이상 사용하지 않아 단일 안전 영역 레이아웃 안내서로 대체했습니다.

Apple에 따른 안전 구역

안전 영역은 전체 인터페이스의 보이는 부분 내에 뷰를 배치하는 데 도움이됩니다. UIKit 정의 뷰 컨트롤러는 컨텐츠 위에 특수 뷰를 배치 할 수 있습니다. 예를 들어, 내비게이션 컨트롤러는 기본보기 컨트롤러의 컨텐츠 위에 내비게이션 바를 표시합니다. 이러한 뷰가 부분적으로 투명하더라도 여전히 그 아래에있는 컨텐츠를 차단합니다. tvOS에서 안전 영역에는 화면의 오버 스캔 삽입물도 포함되어 있는데,이 영역은 화면의 베젤로 덮여있는 영역을 나타냅니다.

아래는 iPhone 8 및 iPhone X 시리즈에서 안전한 영역을 강조한 것입니다.

여기에 이미지 설명을 입력하십시오

safeAreaLayoutGuide속성입니다UIView

높이를 얻으려면 safeAreaLayoutGuide:

extension UIView {
   var safeAreaHeight: CGFloat {
       if #available(iOS 11, *) {
        return safeAreaLayoutGuide.layoutFrame.size.height
       }
       return bounds.height
  }
}

그러면 사진의 화살표 높이가 반환됩니다.

이제 상단 “노치”및 하단 홈 화면 표시기 높이를 얻는 방법은 무엇입니까?

여기에서 우리는 safeAreaInsets

보기의 안전한 영역은 탐색 막대, 탭 막대, 도구 모음 및보기 컨트롤러의보기를 가리는 다른 조상으로 덮여 있지 않은 영역을 반영합니다. tvOS에서 안전 영역은 화면의 베젤에 포함되지 않은 영역을 반영합니다.이 속성의 삽입을보기의 경계 사각형에 적용하여보기의 안전 영역을 얻습니다. 보기가 현재보기 계층 구조에 설치되어 있지 않거나 아직 화면에 표시되지 않으면이 속성의 가장자리 삽입은 0입니다.

다음은 안전하지 않은 영역과 iPhone 8 및 iPhone X 시리즈 중 하나의 가장자리와의 거리를 보여줍니다.

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

탐색 바가 추가되면

여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오

이제 안전하지 않은 지역 높이를 얻는 방법은 무엇입니까? 우리는 사용할 것이다safeAreaInset

여기 해결책이 있지만 중요한 점이 다릅니다.

첫 번째:

self.view.safeAreaInsets

그러면 EdgeInsets가 반환되고 상단과 하단에 액세스하여 삽입 된 부분을 알 수 있습니다.

두번째 것:

UIApplication.shared.windows.first{$0.isKeyWindow }?.safeAreaInsets

첫 번째 뷰 뷰 세트는 탐색 막대가있는 경우 고려되지만 탐색 막대는 창의 safeAreaInsets에 액세스하므로 탐색 막대가 고려되지 않습니다


답변

iOS 11에는 safeArea가 언제 변경되었는지 알려주는 방법이 있습니다.

override func viewSafeAreaInsetsDidChange() {
    super.viewSafeAreaInsetsDidChange()
    let top = view.safeAreaInsets.top
    let bottom = view.safeAreaInsets.bottom
}


답변

나는 CocoaPods의 프레임 워크 및 사례에서 일하고 UIApplication.shared있다 사용할 수없는 다음 내가 사용하는 safeAreaInsets뷰의에서 window:

if #available(iOS 11.0, *) {
    let insets = view.window?.safeAreaInsets
    let top = insets.top
    let bottom = insets.bottom
}