ios 是否有 UIView 调整大小事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4000664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:57:49  来源:igfitidea点击:

Is there a UIView resize event?

iphoneipadios

提问by live-love

I have a view that has rows and columns of imageviews in it.

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

If this view is resized, I need to rearrange the imageviews positions.

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

This view is a subview of another view that gets resized.

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

Is there a way to detect when this view is being resized?

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

采纳答案by Michal

As Uli commented below, the proper way to do it is override layoutSubviewsand layout the imageViews there.

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

If, for some reason, you can't subclass and override layoutSubviews, observing boundsshould work, even when being kind of dirty. Even worse, there is a risk with observing - Apple does not guarantee KVO works on UIKit classes. Read the discussion with Apple engineer here: When does an associated object get released?

如果由于某种原因,您不能子类化和覆盖,即使有点脏layoutSubviews,观察也bounds应该起作用。更糟糕的是,观察存在风险——Apple 不保证 KVO 可以在 UIKit 类上运行。在此处阅读与 Apple 工程师的讨论:关联对象何时发布?

original answer:

原答案:

You can use key-value observing:

您可以使用键值观察:

[yourView addObserver:self forKeyPath:@"bounds" options:0 context:nil];

and implement:

并实施:

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

回答by Rudolf Adamkovi?

In a UIViewsubclass, property observerscan be used:

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

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

Without subclassing, key-value observationwith smart key-pathswill do:

如果没有子类化,使用智能键路径的键值观察将执行以下操作:

var boundsObservation: NSKeyValueObservation?

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

回答by gwang

Create subclass of UIView, and override layoutSubviews

创建 UIView 的子类,并覆盖 layoutSubviews

回答by Warren Stringer

Swift 4 keypath KVO -- This is how I detect autorotate and moving to iPad side panel. Should work work any view. Had to observe the UIView's layer.

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

回答by rekle

You can create a subclass of UIView and override the

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

setFrame:(CGRect)frame

setFrame:(CGRect)frame

method. This is the method called when the frame (i.e. the size) of the view is changed. Do something like this:

方法。这是在视图的框架(即大小)发生变化时调用的方法。做这样的事情:

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

  // Do your custom code here.
}

回答by Adlai Holler

Pretty old but still a good question. In Apple's sample code, and in some of their private UIView subclasses, they override setBounds roughly like:

很老了,但仍然是一个好问题。在 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];
}

Overriding setFrame:is NOT a good idea. frameis derived from center, bounds, and transform, so iOS will not necessarily call setFrame:.

覆盖setFrame:不是一个好主意。frame派生自center,, boundsand transform,所以 iOS 不一定会调用setFrame:.

回答by Dan Rosenstark

If you're in a UIViewController instance, overriding viewDidLayoutSubviewsdoes the trick.

如果您在 UIViewController 实例中,则覆盖viewDidLayoutSubviews可以解决问题。

override func viewDidLayoutSubviews() {
    // update subviews
}