[ios] Interface Builder : UIView의 레이아웃 iOS 6/7 델타는 무엇입니까?

방금 UIView의 구조체 레이아웃 아래에있는 iOS 6/7 Delta 속성을 발견했습니다.

이것은 무엇이며 AutoLayout에서 누락 된 이유는 무엇입니까?

여기에 이미지 설명 입력



답변

이것은 실제로 iOS6에서 iOS7까지의 레이아웃 위치 사이의 델타를 나타냅니다.

iOS7에서 일부보기는 상태 표시 줄을 숨기거나 투명하게 할 수 있으며 사실상보기 위에 오버레이됩니다. 따라서 iOS6에서 UI 요소를 (0.0, 0.0)에 배치하면 상태 표시 줄 아래에 표시되지만 iOS7에서는 상태 표시 줄 아래에 부분적으로 가려진 것처럼 보입니다. 따라서이 경우 레이아웃이 iOS6 및 iOS7에서 동일하게 보이도록 상태 표시 줄 높이 (20.0 포인트)와 일치하는 델타를 원할 것입니다.

자동 레이아웃을 사용하는 경우 이것이 필요하지 않다고 생각하지만 물론 iPad1 지원을 잃게됩니다. 우리 중 많은 사람들이이 시점에서 기꺼이 인정하지 않습니다.


답변

참고 : 얼마 전에이 질문을 발견했지만 NDA가 해제 되었기 때문에 지금은 답변 만 게시하고 있습니다.

AutoLayout에 표시되지 않는 이유는 무엇입니까?

아시다시피 iOS 7은 완전히 새로운 모습을 보여줍니다. UI 요소의 모양이 변경되었지만 일부 크기 (또는 일반적으로 측정 항목)도 변경되었습니다. 이로 인해 iOS 7과 이전 버전을 모두 수용 할 수있는 인터페이스 디자인이 약간 고통 스러울 수 있습니다.

Apple의 공식 라인은 AutoLayout을 사용하여이 문제를 해결하는 것입니다. 이렇게하면 UI 요소를 레이아웃하는 번거 로움이 많이 줄어 듭니다. 특히 비즈니스상의 이유로 iOS 5를 계속 지원해야하거나 인터페이스가 AutoLayout 구현을 어렵게 만드는 방식으로 관리되는 경우 이러한 통합이 쉽게 수행되지 않는 경우가 있습니다. 따라서 Apple은이 틈새 범주에 속하면 작업을 좀 더 쉽게 할 수있는 방법을 제공 한 것으로 보이며이 iOS 6/7 Deltas라고 불렀습니다.

그럼 어떻게하나요?

Interface Builder의 레이블은이 컨텍스트에서 ‘델타’가 의미하는 바에 대해 약간 불분명하지만이 기능에 해당하는 .xib 파일에 포함 된 코드는 좀 더 명확합니다.

<inset key="insetFor6xAndEarlier" minX="-50" minY="-100" maxX="-50" maxY="300"/>

키 이름 insetFor6xAndEarlier은 이것이 수행하는 작업을 명시 적으로 나타냅니다. iOS 7의 이전 버전에서 실행할 때 UI 요소에 대한 대체 삽입을 제공 할 수 있습니다. 예를 들어, 위는 다음과 같은 델타 변경을 정의합니다.

x: 50
y: 100
width: -100
height: 200

.xib에 저장된 값은 인용 된 값과 직접 일치하지 않지만 둘 사이에는 상관 관계가 있습니다.

x: -minX
y: -minY
width: minX + maxX
height: minY + maxY

아래 이미지는 이러한 변경 사항을 시각적으로 보여줍니다. 매우 극단적 인 예이지만 그 능력을 보여주기위한 것입니다. 나는 실제로 단지 몇 픽셀의 델타 변화를 기대할 것입니다.

iOS7보기

iOS6보기

값이 iOS 6보기에 대해 반대임을 알 수 있습니다. 이는 델타가 작업중인 뷰 유형에 상대적이기 때문입니다. iOS 6 용으로 편집하는 경우 iOS 7 용으로 요소를 올바르게 변환하기위한 델타가 있습니다 (위의 예의 반대).

다른 스타일을보기 위해 실행될 OS에 따라 Interface Builder가 표시하는 방식을 변경할 수 있습니다. 이것은 File Inspector-> Interface Builder 문서 (오른쪽 막대의 첫 번째 탭)에 포함되어 있습니다.

인터페이스 스타일 스위치

인터페이스를 직접 코딩하려는 경우 이것이 존재합니까?

직접적으로는 아니지만 코드 내에서 OS 버전에 대한 조건부 검사를 수행하고 그에 따라 올바른 위치 / 크기를 설정하여 동일한 효과를 쉽게 얻을 수 있습니다. 델타 기능은 인터페이스 빌더에 존재합니다. 그 이유는 코드없이 조건부 위치를 지정하는 간단한 방법이 없기 때문이며 인터페이스 빌더의 요점은 UI에 대해 가능한 한 많은 코드를 가져 오는 것입니다.

사무용 겉옷…

Apple은 AutoLayout을 사용할 것을 강력히 권장하며 대부분의 경우 삶을 더 쉽게 만듭니다. 사용할 수없는 경우 (위에서 언급 한 이유로) 델타는 코드에서 수동으로 재배치 할 필요없이 현재 OS의 메트릭에 따라 UI 요소를 적절하게 배치 할 수있는 유연성을 제공합니다. 좋은 예는 상태 표시 줄의 부족을 조정하는 것이지만 다른 많은 사용 사례가 있습니다.

당연히 iOS7 이상용으로 만 개발하는 경우이 기능을 알 필요가 없으며 발견 할 수 없습니다. 자동 레이아웃없이 iOS7 SDK로 빌드 할 때 애플리케이션을 실행하는 iOS6 장치가 필요한 경우에만 델타가 필요합니다.

글을 쓰는 시점 (8 월 21 일),이 기능에 관한 문서 나 WWDC 자료에 언급 된 내용을 찾을 수 없습니다. 나는 장난을 쳤고 약간의 조사 끝에 그것이 내가 발견 한 것입니다.


답변

나는 이것이 이미 대답되었다는 것을 알고 있으며, 자동 레이아웃을 사용하지 않고 여전히 iOS 6.1 및 이전 버전을 지원하려는 사람들에게 도움이 될 수 있기를 바라는 작은 변형을 추가했습니다.

Apple의 전환 가이드 읽기 -이전 버전 지원

‘다음으로보기’를 ‘iOS 7.0 이상’으로 선택하십시오.

여기에 이미지 설명 입력

iOS 7 용 기본 UI. iOS 6의 경우 적절한 델타 값을 제공합니다. 미리보기를 사용하여 iOS 7 및 iOS 6 기기에서 어떻게 렌더링되는지 확인하세요.

여기에 이미지 설명 입력

빠른 단계 :

루트 뷰의 각 직계 자식을 개별적으로 선택하고 ‘Y’값에 20px를 추가합니다.

여기에 이미지 설명 입력

그런 다음 모든 직계 자식을 집합 적으로 선택하고 델타 Y를 -20px로 지정하십시오. 일괄 적으로 또는 개별적으로이 작업을 수행 할 수도 있습니다.

여기에 이미지 설명 입력


답변

AutoLayout은 최소 iOS 6.0이 필요합니다. iOS 5.0을 지원하려면 AutoLayout을 사용할 수 없습니다.

그리고 이러한 델타는 다른 iOS 버전 (주로 iOS 7 및 iOS 버전 7 미만)에서보기 위치를 조정하는 데 사용됩니다.

이 사진을 좋아하는 데 도움이되도록 그 가치를 사용합니다.
여기에 이미지 설명 입력


답변

iOS 6/7 Delta가 작동하는 모습을보기 위해 iOS 6 및 iOS 7 기기 모두에 올바르게 표시되는 SegmentedControl로 데모합니다.

먼저 Storyboard에서 .Xib 또는 ViewController를 선택하십시오. 선택을 취소 를 사용하여 자동 레이아웃 및 “선택 7 이상 아이폰 OS로보기

여기에 이미지 설명 입력

Interface Builder 캔버스에서 origin.y 가 20이 되도록 SegmentedControl을 배치하십시오 . iOS 6/7 Delta에서 DeltaY로 -20을 선택하십시오.

여기에 이미지 설명 입력

이렇게하면 iOS 6 및 iOS 7 기기의 상태 표시 줄 아래에 SegmentedControl이 배치됩니다.

여기에 이미지 설명 입력
여기에 이미지 설명 입력

iOS 7 상태 표시 줄에 대한 개발자 가이드의 또 다른 유용한 인용문

델타는 각보기에 대해 개별적으로 설정 될 수 있으며 예상대로 작동합니다. 스토리 보드 또는 펜촉이 iOS 6으로 표시되도록 설정되어있는 경우 델타를 설정하면 iOS 7에서 실행할 때 설정된 델타 양만큼 해당 뷰가 이동 및 / 또는 크기가 조정됩니다. 또는 스토리 보드 또는 펜촉이보기로 설정된 경우 iOS 7에서는 iOS 6에서 실행할 때 델타가 적용됩니다.


답변

AutoLayout을 사용하는 경우 Delta를 사용할 수 없습니다. 이것을 시도하십시오 (iOS6을 실행하는 iPhone 4s에서 테스트 됨) :

- (void) viewWillLayoutSubviews {

//iOS 6 workaround offset
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) {

    self.view.clipsToBounds = YES;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = 0.0;
    screenHeight = screenRect.size.width;
    CGRect screenFrame = CGRectMake(0, -20, self.view.frame.size.width,self.view.frame.size.height+10);

    self.view.frame = screenFrame;
}
}


답변