使用 viewDidLayoutSubviews 为视图控制器安排控件时,我遇到了奇怪的行为。我在界面构建器的视图控制器上放置了多个控件(标签、文本框、日期选择器和分段控件)。在 viewDidLoad 中,我隐藏了其中一些控件,其余的需要重新排列(向上移动),以便隐藏控件所在的位置没有间隙。
当视图加载时,viewDidLayoutSubviews 会触发并且控件都按照需要进行排列。但是,如果您点击分段控件,它会“丢失”其帧原点并从 IB 恢复到其原始位置。什么触发会使分段控件失去其帧原点?
然后,如果您编辑文本字段,viewDidLayoutSubviews 将再次触发,并且分段控件将移回所需位置。这似乎不合适——我没有执行任何 setFrame 或其他需要这样做的操作。
- (void)viewDidLoad {
[super viewDidLoad];
// arbitrarily hide two of the controls
_textField2.hidden = YES;
_textField4.hidden = YES;
}
- (void)viewDidLayoutSubviews {
// move the controls up in the view if any preceding controls are hidden
float currentYPosition = _textField1.frame.origin.y;
NSArray *arrayControls = @[_textField1, _textField2, _segmentedControl1, _textField3, _textField4, _textField5];
for (int i=0; i < arrayControls.count; i++) {
// move the associated control...also capture the offset to the next label/control
UIView <NSObject> *object = (UIView <NSObject> *)[arrayControls objectAtIndex:i];
float newYPosition = [self rearrangeFrame:object withCurrentYPosition:currentYPosition];
// update our reference to the current Y position
currentYPosition = newYPosition;
}
}
- (float)rearrangeFrame:(id)controlObject withCurrentYPosition:(float)topSpaceToSuperview {
// input: control on the view that needs to be rearranged
// output: the updated y coordinate for the next control
float padding = 3.0f;
if ([controlObject conformsToProtocol:@protocol(NSObject)]) {
UIView <NSObject> *object = (UIView <NSObject> *) controlObject;
if (object.hidden) {
// return a box with a height of 0 if the control is hidden
[object setFrame:CGRectMake(object.frame.origin.x, topSpaceToSuperview, object.frame.size.width, 0)];
return topSpaceToSuperview;
} else {
// update the y position of the control's frame origin
[object setFrame:CGRectMake(object.frame.origin.x, topSpaceToSuperview, object.frame.size.width, object.frame.size.height)];
return topSpaceToSuperview + object.frame.size.height + padding;
}
} else {
return topSpaceToSuperview;
}
}