UISegmentedControl 不会在 viewDidLayoutSubviews 之后保留其框架原点



在使用viewDidLayoutSubviews为视图控制器排列控件时,我遇到了奇怪的行为。 我将多个控件(标签、文本框、日期选择器和分段控件)放在界面生成器的视图控制器上。 在viewDidLoad中,我隐藏了其中一些控件,其余控件需要重新排列(向上移动),以便隐藏控件的位置没有间隙。

当视图加载时,将触发 viewDidLayoutSubviews,并且控件都按需要排列。 但是,如果您点击分段控件,它会"丢失"其帧原点并从 IB 恢复到其原始位置。 是什么触发会使分段控件失去其帧原点?

然后,如果编辑文本字段,视图DidLayoutSubviews 将再次触发,并且分段控件将移回所需位置。 这似乎不合适 - 我没有执行任何需要这样做的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;
    }
}

这可能是因为自动布局处于打开状态(默认情况下处于打开状态)。使用自动布局移动视图时,必须更改约束,而不是设置框架。所以要解决这个问题。您需要关闭自动布局或更改代码以使用约束。

最新更新