更改约束常量的正确方法是什么

时间:2017-07-16 09:14:34

标签: objective-c ios-autolayout

我必须改变约束但是通过改变约束常数, 我得到重复 - Xcode发出警告。

我可以看到一个约束是旧约束,另一个约束是新约束, 和他们的记忆地址不同。

创建和设置视图以处理约束更改的正确方法是什么?

我的示例我有一个mainView添加到self.view,提供的视图 当你扩展UIViewController时。 " self.view"提供并没有设置约束。

Main MainView是我的容器,我想在键盘出现时将其高度调整到键盘上方。

viewDidLoad中:

- (void)viewDidLoad {

   [super viewDidLoad];

   _mainView = [UIView new];
   _mainView.translatesAutoresizingMaskIntoConstraints = NO;
   [self.view addSubview:_mainView];
}

viewWillLayoutSubviews:

-(void)viewWillLayoutSubviews {

 [super viewWillLayoutSubviews];

 //moved to viewDidLoad
 //self.mainView.translatesAutoresizingMaskIntoConstraints = NO;

//top
[[self view] addConstraint:[NSLayoutConstraint constraintWithItem:_mainView
                                                        attribute:NSLayoutAttributeTop
                                                        relatedBy:NSLayoutRelationEqual
                                                           toItem:self.view
                                                        attribute:NSLayoutAttributeTop
                                                       multiplier:1.0
                                                         constant:0]];

//bottom
_mainBottomContraint = [NSLayoutConstraint constraintWithItem:_mainView
                                                    attribute:NSLayoutAttributeBottom
                                                    relatedBy:NSLayoutRelationEqual
                                                       toItem:self.view
                                                    attribute:NSLayoutAttributeBottom
                                                   multiplier:1.0
                                                     constant:_keyboardOffset];

[[self view] addConstraint:_mainBottomContraint];

//left
[[self view] addConstraint:[NSLayoutConstraint constraintWithItem:_mainView
                                                        attribute:NSLayoutAttributeLeft
                                                        relatedBy:NSLayoutRelationEqual
                                                           toItem:self.view
                                                        attribute:NSLayoutAttributeLeft
                                                       multiplier:1.0
                                                         constant:0]];

//right
[[self view] addConstraint:[NSLayoutConstraint constraintWithItem:_mainView
                                                        attribute:NSLayoutAttributeRight
                                                        relatedBy:NSLayoutRelationEqual
                                                           toItem:self.view
                                                        attribute:NSLayoutAttributeRight
                                                       multiplier:1.0
                                                         constant:0]];

-

每当我改变约束常量时,我​​都会得到重复的约束, 再次调用viewWillLayoutSubviews并重新创建约束。 如何在不重新创建的情况下改变约束?或者在这里使用的正确模式是什么。

keyboardWillShow - 更改约束(setConstant)

- (void)keyboardWillShow:(NSNotification*)aNotification {

    if (![_chatTextField isFirstResponder]) {
        return;
    }

    CGSize tabBarSize = [[[self tabBarController] tabBar] bounds].size;    
    NSDictionary* info = [aNotification userInfo];

    NSTimeInterval duration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve curve = [[info objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue];

    CGSize kbSize = [info[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    CGRect bkgndRect = _mainView.frame;
    bkgndRect.size.height -= kbSize.height-tabBarSize.height;

    //animate with keyboard
    _keyboardOffset = -kbSize.height-tabBarSize.height;
    [_mainBottomContraint setConstant:_keyboardOffset];
    [self.view setNeedsLayout];

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve     animations:^{
        [_mainView layoutIfNeeded];

    } completion:nil];
}

日志

内存地址 0x174286450

的约束1

内存地址 0x174288660

的约束2
(
"<NSLayoutConstraint:0x174286450 UIView:0x14fd5e5b0.bottom == UIView:0x14fe5edd0.bottom - 271   (active)>",
"<NSLayoutConstraint:0x174288660 UIView:0x14fd5e5b0.bottom == UIView:0x14fe5edd0.bottom   (active)>"
)

2 个答案:

答案 0 :(得分:1)

在我看来,你添加了_mainBottomContraint两次。首先,你创建一个_mainBottomContraint并保留它,当键盘改变时,_mainBottomContraint.constaints改变,如果self.view.subviews中的视图改变了框架,系统将发布通知,并且viewcontroller将接收它,并调用viewWillLayoutSubviews,就像视图将调用layoutSubviews.So你创建一个_mainBottomContraint,所以现在,有两个bottomContraint,你得到一个警告。 你应该只添加一次约束,你可以在viewDidLoad函数中添加它们,它会很好。

答案 1 :(得分:0)

呼叫

subview.translatesAutoresizingMaskIntoConstraints = NO;

在子视图之前将其添加到另一个视图。否则会自动创建一些约束,从而导致警告。

- (void)viewDidLoad { 
[super viewDidLoad]; _mainView = [UIView new]; 
self.mainView.translatesAutoresizingMaskIntoConstraints = NO; 

[self.view addSubview:_mainView]; 
}

然后保存您创建的约束的引用(就像您一样),并在需要时更改它们。