繁体   English   中英

可以让superView拦截layoutSubviews:来自子视图吗?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM