문제

나는 얻지 못하는 맞춤형보기가 있습니다 layoutSubview 애니메이션 중 메시지.

화면을 채우는보기가 있습니다. 화면 하단에 NAV 막대의 높이를 변경하면 인터페이스 빌더에서 올바르게 크기를 조정하는 사용자 정의 서브 뷰가 있습니다. layoutSubviews 보기가 생성 될 때 호출되지만 다시는 절대 없습니다. 내 하위 뷰가 올바르게 배치되었습니다. 통화 내 상태 표시 줄을 전환하면 하위 뷰의 layoutSubviews 메인 뷰가 크기 조정을 애니메이션하는 경우에도 전혀 호출되지 않습니다.

어떤 상황에서 layoutSubviews 실제로 전화?

나는 가지고있다 autoresizesSubviews 로 설정 NO 내 사용자 정의보기. 인터페이스 빌더에는 상단 및 하단 스트럿과 수직 화살표 세트가 있습니다.


퍼즐의 또 다른 부분은 창을 키워야한다는 것입니다.

[window makeKeyAndVisible];

그렇지 않으면 하위 뷰가 자동으로 조정되지 않습니다.

도움이 되었습니까?

해결책 5

시뮬레이션 된 화면 요소가 켜져있는보기 (상태 표시 줄 등)에서 스프링을 변경할 수 없다는 인터페이스 빌더의 주장에 대한 솔루션을 추적했습니다. 스프링이 메인 뷰를 위해 꺼져 있었기 때문에, 그 뷰는 크기를 바꿀 수 없었으므로 통화 내 막대가 나타날 때 전체적으로 스크롤되었습니다.

시뮬레이션 된 기능을 끄고 뷰를 조정하고 스프링을 올바르게 설정하면 애니메이션이 발생하고 내 메소드가 호출됩니다.

디버깅의 추가 문제는 메뉴를 통해 통화 내 상태가 전환 될 때 시뮬레이터가 앱을 종료한다는 것입니다. 종료 앱 = 디버거가 없습니다.

다른 팁

나는 비슷한 질문이 있었지만 답에 만족하지 않았으므로 (또는 그물에서 찾을 수있는 것) 실제로 시도해 보았고 여기에 내가 얻은 것입니다.

  • init 원인이되지 않습니다 layoutSubviews (duh)
  • addSubview: 원인layoutSubviews 추가되는 뷰에서 호출 되려면 (대상보기)에 추가되는보기 및 대상의 모든 하위 뷰
  • 보다 setFrame지능적으로 전화합니다 layoutSubviews 프레임의 크기 매개 변수가 다른 경우에만 프레임 설정이있는보기에서
  • uiscrollview 원인을 스크롤합니다 layoutSubviews ScrollView 및 SuperView에서 호출됩니다.
  • 장치를 회전하면 호출됩니다layoutSubview 상위보기 (응답 뷰 콘트롤러 기본보기)
  • 조회수를 조정하면 호출됩니다 layoutSubviews 수퍼 뷰에서

내 결과 - http://blog.logichigh.com/2011/03/16/when-does-layoutsubviews-get-called/

@Badpirate의 이전 답변을 바탕으로 조금 더 실험하고 설명/수정을 제시했습니다. 나는 그것을 발견했다 layoutSubviews: 다음과 같은 경우에만 뷰에서 호출됩니다.

  • 그 자체 범위 (프레임 아님) 변경되었습니다.
  • 직접 서브 뷰 중 하나의 범위가 변경되었습니다.
  • 서브 뷰가 뷰에 추가되거나 뷰에서 제거됩니다.

몇 가지 관련 세부 사항 :

  • 새로운 값이 다른 경우에만 범위가 변경되는 것으로 간주됩니다. 다른 기원을 포함하여. 구체적으로 주목하십시오. 이것이 바로 그 이유입니다 layoutSubviews: Uiscrollview 스크롤 할 때마다 호출되며, 바운드의 원점을 변경하여 스크롤을 수행하므로 스크롤을 수행합니다.
  • 프레임을 변경하면 크기가 변경된 경우에만 경계가 변경됩니다. 바운드 속성으로 전파되는 유일한 것입니다.
  • 보기 계층 구조에 아직없는 뷰의 범위 변경으로 인해 layoutSubviews: 보기가 결국 View 계층에 추가 될 때.
  • 그리고 완전성을 위해 :이 트리거는 그렇지 않습니다 곧장 LayoutSubviews를 호출하지만 오히려 전화하십시오 setNeedsLayout, 깃발을 설정/제기합니다. 모든 뷰에 대해 런 루프의 각 반복 보기에서 계층 구조에서,이 깃발은 확인됩니다. 깃발이 제기되는 각보기에 대해 layoutSubviews: 그것에 호출되고 깃발이 재설정됩니다. 더 높은 뷰는 계층 구조가 먼저 확인/호출됩니다.

https://developer.apple.com/library/prerelease/tvos/documentation/windowsviews/conceptual/viewpg_iphoneos/creatingviews/creatingviews.html#//apple_ref/doc/uid/tp40009503-ch5-sw1

다음 이벤트 중 하나가보기에서 발생할 때마다 레이아웃 변경이 발생할 수 있습니다.

ㅏ. 보기 경계의 크기는 사각형이 변경됩니다.
비. 인터페이스 방향 변경이 발생하며, 일반적으로 루트보기의 바운드 사각형의 변화를 유발합니다.
씨. 뷰의 레이어와 관련된 핵심 애니메이션 하위 계층 세트는 레이아웃이 변경되어야합니다.
디. 응용 프로그램은 호출하여 레이아웃이 발생합니다setNeedsLayout또는layoutIfNeeded견해의 방법.
이자형. 귀하의 응용 프로그램은setNeedsLayout보기의 기본 레이어 객체의 방법.

일부 포인트 Badpirate의 대답 부분적으로 만 사실입니다.

  1. 을 위한 addSubView 가리키다

    addSubview 뷰가 추가되는 뷰에서 호출되며 (대상보기) 추가되는보기 및 대상의 모든 하위 뷰가 호출됩니다.

    보기 (대상 뷰) Autoresize 마스크에 따라 다릅니다. Autoresize 마스크가 켜져 있으면 각각에 레이아웃 서브 뷰가 호출됩니다. addSubview. Autoresize 마스크가없는 경우 뷰의 (대상보기) 프레임 크기가 변경 될 때만 레이아웃 서브 뷰가 호출됩니다.

    예 : UIVIWE를 프로그래밍 방식으로 만든 경우 (기본적으로 자동화 된 마스크가 없음) LayoutSubview는 UIView 프레임이 매번 변경되지 않은 경우에만 호출됩니다. addSubview.

    이 기술을 통해 응용 프로그램의 성능도 증가합니다.

  2. 장치 회전 지점의 경우

    장치 회전은 부모보기에서 만 레이아웃을 호출합니다 (응답 뷰 컨트롤러의 기본보기)

    VC가 VC 계층에있을 때만 사실 일 수 있습니다 (루트 window.rootViewController), 이것은 가장 일반적인 경우입니다. iOS 5에서는 VC를 생성하지만 다른 VC에 추가되지 않으면 장치가 회전 할 때이 VC가 눈에 띄지 않습니다. 따라서 레이아웃 서브 뷰를 호출함으로써 그 견해는 눈에 띄지 않을 것입니다.

부름[self.view setNeedsLayout]; ViewController에서 ViewDidlayoutSubviews를 호출합니다

당신은 layoutifneeded를 보셨습니까?

문서 스 니펫은 다음과 같습니다. 애니메이션 중에이 방법을 명시 적으로 호출하면 애니메이션이 작동합니까?

Layoutifneeded는 필요한 경우 하위 뷰를 제시합니다.

- (void)layoutIfNeeded

토론이 방법을 사용하여 그리기 전에 하위 뷰의 레이아웃을 강제합니다.

iPhone OS 2.0 이상에서 사용할 수 있습니다.

SDK에서 OpenGL 앱을 SDK 3으로 마이그레이션 할 때 레이아웃 서브 뷰는 더 이상 호출되지 않았습니다. 많은 시행 착오 후 마침내 mainwindow.xib를 열고 창 객체를 선택하고 검사관에서 창자 속성 탭 (가장 왼쪽)을 선택하고 "시작시 표시"를 확인했습니다. SDK 3에서는 여전히 레이아웃 서브 뷰 호출을 일으키는 데 사용되었지만 4는 아닙니다.

6 시간의 좌절감이 끝났습니다.

다소 모호하지만 잠재적으로 중요한 경우 layoutSubviews 절대 불러지는 것은 다음과 같습니다.

import UIKit

class View: UIView {

    override class var layerClass: AnyClass { return Layer.self }

    class Layer: CALayer {
        override func layoutSublayers() {
            // if we don't call super.layoutSublayers()...
            print(type(of: self), #function)
        }
    }

    override func layoutSubviews() {
        // ... this method never gets called by the OS!
        print(type(of: self), #function)
    }
}

let view = View(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top