1

使用 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;
    }
}
4

1 回答 1

0

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

于 2013-09-17T01:04:04.097 回答