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

时间:2011-08-10 12:59:34

标签: iphone cocoa-touch uiview uikit layoutsubviews

为了允许灵活的布局,我想创建一个子类UIView,它覆盖layoutSubviews:以自动地将所有子视图布局在彼此之下,并且每次调整其子视图的大小时都会继续执行此操作。

然而,我能想到让superview知道它应该调用layoutSubviews:的唯一方法是在每个子视图中覆盖该方法,我想尝试避免(我想要的)人们可以将任意UIViews添加到superview中并进行处理。

当子视图更改其大小时,超级视图是否有办法调用layoutSubviews:没有将任何代码添加到相关子视图中?

2 个答案:

答案 0 :(得分:0)

您可以向班级添加类别,并尝试从该类别中覆盖layoutSubviews:。 (这种技术has been suggested for customizing navigation bars,它也可以在这里工作。)

以下是制作类别taken from my answer here的方法。在您的情况下,请务必将UIView替换为UINavigationController

按Command + N或打开“新建文件”对话框。接下来,从Cocoa Touch菜单中选择“Objective-C category”:

Creating a category

单击“下一步”,系统将提示您输入要作为类别添加方法的类的名称。看起来应该是这样的:

Making a Category on the NavBar

然后,您应该最终得到一个保存文件对话框。这里有关于约定的快速说明。惯例是在原始类之后命名一个类别,加号,然后描述您要添加的内容。这是你的看法:

Category Naming Convention

保存文件后,您需要获得以下内容:

Empty Category

修改

如果你想在没有类别的情况下继续这样做,那么最好的办法是创建一个UIView的子类,然后将类子类化为你想要的自定义行为。与类别相比的另一个优点是,您的方法仅适用于显式使用自定义类的位置。在类别中,该方法随处可见。

祝你好运!

答案 1 :(得分:0)

您可以使用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
}