iOS 子视图调整大小时多次调用 LayoutSubviews
iOS LayoutSubviews being called multiple times when a subview resizes
在我的程序中,我已经开始在 init 方法中对对象进行所有初始化,但没有设置框架,然后在 layoutSubviews 中我为这些对象设置了框架以确保它们设置正确。
首先,这种正确的做法是在没有设置框架的情况下初始化 init 函数中的所有对象,然后在 layoutSubviews 中设置它们的每个框架。我担心的原因是它经常被调用。
所以我有一个 UIView subclass,我在 layoutSubviews
中调用这些方法
- (void)layoutSubviews
{
[super layoutSubviews];
[self.filterSwitcherView setFrame:self.viewFrame];
[self.drawingView setFrame:self.viewFrame];
[self.textView setFrame:self.textViewFrame];
[self.colorPicker setFrame:self.colorPickerFrame];
}
这目前工作正常,所有对象都已正确设置,但问题出在我的颜色选择器中 class 当用户触摸屏幕时,我调整了颜色选择器的框架,并通过这样做调用了此方法从子视图 colorPicker 重新调整一个框架,因为它已经在子视图中被修改了。子视图导致父视图 layoutSubview 被调用,这不是我需要的。
我的问题是,有没有办法阻止这种行为的发生,或者我不应该使用 layoutSubviews 来设置框架,因为有人告诉我这是以编程方式制作视图的更好方法?
在我的脑海中,有两种方法可以解决这个问题。您可以将此代码移动到初始化视图的位置,在 init
、initWithFrame:
或 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 class 正在处理触摸方法以调整其自身的框架。相反,您应该在 colorPicker 的超级视图 class 中处理触摸方法,并让该超级视图 class 调整 colorPicker 的框架以响应触摸。
此外,我建议在 initWithFrame:
中进行所有 UI 初始化,而不是 init
。原因是因为在 UIView 上调用 init
最终会调用 initWithFrame:
.
在我的程序中,我已经开始在 init 方法中对对象进行所有初始化,但没有设置框架,然后在 layoutSubviews 中我为这些对象设置了框架以确保它们设置正确。
首先,这种正确的做法是在没有设置框架的情况下初始化 init 函数中的所有对象,然后在 layoutSubviews 中设置它们的每个框架。我担心的原因是它经常被调用。
所以我有一个 UIView subclass,我在 layoutSubviews
中调用这些方法- (void)layoutSubviews
{
[super layoutSubviews];
[self.filterSwitcherView setFrame:self.viewFrame];
[self.drawingView setFrame:self.viewFrame];
[self.textView setFrame:self.textViewFrame];
[self.colorPicker setFrame:self.colorPickerFrame];
}
这目前工作正常,所有对象都已正确设置,但问题出在我的颜色选择器中 class 当用户触摸屏幕时,我调整了颜色选择器的框架,并通过这样做调用了此方法从子视图 colorPicker 重新调整一个框架,因为它已经在子视图中被修改了。子视图导致父视图 layoutSubview 被调用,这不是我需要的。
我的问题是,有没有办法阻止这种行为的发生,或者我不应该使用 layoutSubviews 来设置框架,因为有人告诉我这是以编程方式制作视图的更好方法?
在我的脑海中,有两种方法可以解决这个问题。您可以将此代码移动到初始化视图的位置,在 init
、initWithFrame:
或 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 class 正在处理触摸方法以调整其自身的框架。相反,您应该在 colorPicker 的超级视图 class 中处理触摸方法,并让该超级视图 class 调整 colorPicker 的框架以响应触摸。
此外,我建议在 initWithFrame:
中进行所有 UI 初始化,而不是 init
。原因是因为在 UIView 上调用 init
最终会调用 initWithFrame:
.