iOS 布局子视图在子视图调整大小时被多次调用



在我的程序中,我已经开始在init方法中对对象进行所有初始化,而无需设置框架,然后在layoutSubviews中,我为这些对象设置了框架以确保它们已正确设置。

首先,这是在 init 函数中初始化所有对象而不设置框架的正确做法,然后在 layoutSubviews 中设置它们的每个帧。 我担心的原因是它经常被调用。

所以我有一个 UIView 子类,我在布局子视图中调用这些方法

- (void)layoutSubviews 
{
    [super layoutSubviews];
    [self.filterSwitcherView setFrame:self.viewFrame];
    [self.drawingView setFrame:self.viewFrame];
    [self.textView setFrame:self.textViewFrame];
    [self.colorPicker setFrame:self.colorPickerFrame];
}

这目前工作正常,所有对象都设置正确,但问题出在我的 colorPicker 类中,当用户触摸屏幕时,我调整了颜色选择器的框架,通过这样做,此方法从子视图 colorPicker 调用,它重新调整了一个不应该的框架,因为它已经在子视图中被修改了。 子视图导致超级视图布局子视图被调用,这不是我需要的。

我的问题是,有没有办法阻止这种行为的发生,或者我不应该使用 layoutSubviews 来设置框架,因为我被告知这是以编程方式制作视图的更好方法?

在我的头顶上,有两种方法可以解决这个问题。您可以将此代码移动到初始化视图的位置,可以是 initinitWithFrame:initWithCoder: ,具体取决于您使用的内容。最好创建一个单独的方法来初始化视图的所有内容,并从所有init方法调用它,以确保无论您如何实例化视图,它始终正确初始化。

或者,如果要将代码保留在 layoutSubviews 中,请在@interface中添加一个布尔值以标记帧已设置。

@interface MyView : UIView
@property (nonatomic, assign) BOOL framesAreSet;
@end

然后,当您设置框架时,检查您是否已经这样做

- (void)layoutSubviews 
{
    [super layoutSubviews];
    if (!_framesAreSet)
    {
        [self.filterSwitcherView setFrame:self.viewFrame];
        [self.drawingView setFrame:self.viewFrame];
        [self.textView setFrame:self.textViewFrame];
        [self.colorPicker setFrame:self.colorPickerFrame];
        _framesAreSet = YES;
    }
}

您的问题可能是您的 colorPicker 类正在处理触摸方法来调整自己的框架。相反,您应该在 colorPick 的超级视图类中处理触摸方法,并让该超级视图类调整颜色选取器的框架以响应触摸。

另外,我建议在 initWithFrame: 中执行所有 UI 初始化,而不是 init 。原因是因为在UIView上调用init最终会调用initWithFrame:

最新更新