是否有UIView调整大小事件?

时间:2010-10-22 20:21:42

标签: iphone ipad ios

我有一个包含图像视图行和列的视图。

如果调整此视图的大小,我需要重新排列imageviews位置。

此视图是另一个调整大小的视图的子视图。

有没有办法检测何时调整此视图的大小?

7 个答案:

答案 0 :(得分:91)

正如Uli在下面评论的那样,正确的方法是覆盖layoutSubviews并在那里布局imageViews。

如果由于某种原因,您无法继承和覆盖layoutSubviews,则观察bounds应该有效,即使是有点脏。更糟糕的是,观察存在风险 - Apple不保证KVO可以在UIKit类上运行。在此处阅读与Apple工程师的讨论:When does an associated object get released?

原始回答:

您可以使用键值观察:

[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:
    }
}

答案 1 :(得分:81)

UIView子类中,可以使用属性观察者

override var bounds: CGRect {
    didSet {
        // ...
    }
}

如果没有子类化,使用智能密钥路径键值观察将会:

var boundsObservation: NSKeyValueObservation?

func beginObservingBounds() {
    boundsObservation = observe(\.bounds) { capturedSelf, _ in
        // ...
    }
}

答案 2 :(得分:26)

创建UIView的子类,并覆盖layoutSubviews

答案 3 :(得分:7)

相当古老,但仍然是个好问题。在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源自centerboundstransform,因此iOS不一定会调用setFrame:

答案 4 :(得分:7)

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()
    //...
}

答案 5 :(得分:6)

您可以创建UIView的子类并覆盖

SETFRAME:(的CGRect)帧

方法。这是在改变视图的帧(即大小)时调用的方法。做这样的事情:

- (void) setFrame:(CGRect)frame
{
  // Call the parent class to move the view
  [super setFrame:frame];

  // Do your custom code here.
}

答案 6 :(得分:-3)

如果你在UIViewController实例中,覆盖viewDidLayoutSubviews就可以了。

override func viewDidLayoutSubviews() {
    // update subviews
}