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
Is there a UIView resize event?
提问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 layoutSubviews
and layout the imageViews there.
正如 Uli 在下面评论的那样,正确的方法是覆盖layoutSubviews
并在那里布局 imageViews。
If, for some reason, you can't subclass and override layoutSubviews
, observing bounds
should 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 UIView
subclass, 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. frame
is derived from center
, bounds
, and transform
, so iOS will not necessarily call setFrame:
.
覆盖setFrame:
不是一个好主意。frame
派生自center
,, bounds
and transform
,所以 iOS 不一定会调用setFrame:
.
回答by Dan Rosenstark
If you're in a UIViewController instance, overriding viewDidLayoutSubviews
does the trick.
如果您在 UIViewController 实例中,则覆盖viewDidLayoutSubviews
可以解决问题。
override func viewDidLayoutSubviews() {
// update subviews
}