[英]Possible to make superView intercept layoutSubviews: from subviews?
为了实现灵活的布局,我想创建一个子类 UIView 来覆盖layoutSubviews:
自动将其所有子视图布置在彼此之下,并且每次调整其子视图的大小时都会继续这样做。
但是,我能想到让超级视图知道它应该调用layoutSubviews:
的唯一方法是在其每个子视图中覆盖该方法,这是我想尝试避免的(我希望人们能够添加任意 UIViews 到 superview 并得到照顾)。
有没有办法让超级视图调用layoutSubviews:
每当子视图更改其大小时,而不向相关子视图添加任何代码?
您可以将类别添加到 class 并尝试覆盖layoutSubviews:
从类别中。 (此技术已被建议用于自定义导航栏,它也可以在这里工作。)
以下是你如何制作一个类别, 取自我在这里的回答。 在您的情况下,请记住将UIView
替换为UINavigationController
。
点击 Command+N 或打开“新建文件”对话框。 接下来,从 Cocoa 触摸菜单中选择“Objective-C 类别”:
单击下一步,系统将提示您输入您想将方法添加到的 class 的名称作为类别。 它应该看起来像这样:
然后,您应该会看到一个保存文件对话框。 这里是关于约定的快速说明。 约定是在原始 class 之后命名一个类别,加号,然后是您要添加的内容的描述。 您的可能如下所示:
保存文件后,您将需要获得以下内容:
编辑:
如果您想提前 go 并在没有类别的情况下执行此操作,那么您最好的选择是创建 UIView 的子类,然后在任何您想要自定义行为的地方创建 class 的子类。 与类别相比的另一个优势是,您的方法仅适用于您明确使用自定义 class 的情况。 在类别中,该方法被添加到任何地方。
祝你好运!
您可以使用 KVO 来观察每个子视图的frame
属性。 每次添加子视图时,您都需要将自己添加为观察者,并在删除子视图时删除观察 - 您可以在您的超级视图中覆盖didAddSubview:
和willRemoveSubview:
来做到这一点。
- (void)didAddSubview:(UIView *)subview {
[subview addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)willRemoveSubview:(UIView *)subview {
[subview removeObserver:self forKeyPath:@"frame"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"frame"]) {
// Do your layout here...
}
}
- (void)dealloc {
// You might need to remove yourself as an observer here, in case
// your subviews are still used by others
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.