답변:
Uli가 아래에 언급했듯이 적절한 방법 layoutSubviews
은 imageViews를 재정의 하고 레이아웃하는 것입니다.
어떤 이유로 하위 클래스를 만들고을 재정의 할 수없는 layoutSubviews
경우 관찰 bounds
은 더러워진 경우에도 작동합니다. 더 나쁜 것은 관찰하는 데 위험이 있습니다. Apple은 KVO가 UIKit 클래스에서 작동한다고 보장하지 않습니다. 여기에서 Apple 엔지니어와의 토론을 읽어보십시오. 관련 개체는 언제 릴리스됩니까?
원래 답변 :
키-값 관찰을 사용할 수 있습니다.
[yourView addObserver:self forKeyPath:@"bounds" options:0 context:nil];
구현 :
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (object == yourView && [keyPath isEqualToString:@"bounds"]) {
// do your stuff, or better schedule to run later using performSelector:withObject:afterDuration:
}
}
viewWillTransition
등 등
layoutSubviews
뷰의 현재 크기에 따라 다른 하위 뷰를 추가 / 제거하고 다른 제약 조건을 추가 / 제거해야하는 경우 여전히 권장되는 방법을 사용 하고 있습니까?
A의 UIView
서브 클래스, 부동산 전문가들은 사용할 수 있습니다 :
override var bounds: CGRect {
didSet {
// ...
}
}
서브 클래 싱없이 스마트 키 경로를 사용한 키-값 관찰 은 다음을 수행합니다.
var boundsObservation: NSKeyValueObservation?
func beginObservingBounds() {
boundsObservation = observe(\.bounds) { capturedSelf, _ in
// ...
}
}
frame
파생 및 런타임 계산 속성입니다. 당신이 그렇게 할 아주 똑똑하고 아는 이유가 없다면 이것을 무시하지 마십시오. 그렇지 않으면 : bounds
또는 (더 나은)을 사용하십시오 layoutSubviews
.
override var bounds: CGRect { didSet { layer.cornerRadius = bounds.size.width / 2 }}
UIView의 하위 클래스를 만들고 layoutSubview를 재정의합니다.
Swift 4 keypath KVO-이것이 iPad 측면 패널로의 자동 회전 및 이동을 감지하는 방법입니다. 어떤 관점에서 작동해야합니다. UIView의 레이어를 관찰해야했습니다.
private var observer: NSKeyValueObservation?
override func viewDidLoad() {
super.viewDidLoad()
observer = view.layer.observe(\.bounds) { object, _ in
print(object.bounds)
}
// ...
}
override func viewWillDisappear(_ animated: Bool) {
observer?.invalidate()
//...
}
.layer
트릭을했다! 왜 사용 view.observe
이 작동하지 않는지 아십니까?
UIView의 하위 클래스를 만들고 재정의 할 수 있습니다.
setFrame : (CGRect) 프레임
방법. 뷰의 프레임 (즉, 크기)이 변경 될 때 호출되는 메서드입니다. 다음과 같이하십시오.
- (void) setFrame:(CGRect)frame
{
// Call the parent class to move the view
[super setFrame:frame];
// Do your custom code here.
}
setFrame:
호출되지 않았습니다 . 참고 : 자동 레이아웃 및 iOS 7.0을 사용하고 있습니다. UITextView
layoutSubviews:
setFrame:
. frame
파생 속성입니다. 내 대답을 참조하십시오
꽤 오래되었지만 여전히 좋은 질문입니다. Apple의 샘플 코드와 일부 개인 UIView 하위 클래스에서는 다음과 같이 setBounds를 재정의합니다.
-(void)setBounds:(CGRect)newBounds {
BOOL const isResize = !CGSizeEqualToSize(newBounds.size, self.bounds.size);
if (isResize) [self prepareToResizeTo:newBounds.size]; // probably saves
[super setBounds:newBounds];
if (isResize) [self recoverFromResizing];
}
재정의 setFrame:
는 좋은 생각이 아닙니다. frame
에서 파생 center
, bounds
그리고 transform
아이폰 OS가 반드시 호출하지 않도록, setFrame:
.
setBounds:
프레임 속성을 설정할 때도 호출되지 않습니다 (적어도 iOS 7.1에서는). 이것은 추가 메시지를 피하기 위해 Apple이 추가 한 최적화 일 수 있습니다.
frame
와는 bounds
뷰의 기본에서 파생 된 CALayer
; 그냥 레이어의 게터를 호출합니다. 그리고 setFrame:
반면, 레이어의 프레임을 설정 setBounds:
세트 레이어 경계입니다. 따라서 둘 중 하나만 무시할 수 없습니다. 또한 layoutSubviews
과도하게 호출되기 때문에 (지오메트리 변경뿐만 아니라) 항상 좋은 옵션이 아닐 수도 있습니다. 아직 찾고 있습니다 ...
UIViewController 인스턴스에있는 경우 재정의 viewDidLayoutSubviews
가 트릭을 수행합니다.
override func viewDidLayoutSubviews() {
// update subviews
}
UIView
인스턴스와 UIViewController
인스턴스 간의 관계를 발견했을 수 있습니다 . 따라서 UIView
VC가 연결되지 않은 인스턴스 가있는 경우 다른 답변은 훌륭하지만 VC에 연결되면이 사람이 바로 그 사람입니다. 귀하의 경우에는 해당되지 않습니다.