我必须改变约束但是通过改变约束常数, 我得到重复 - 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)>"
)
答案 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];
}
然后保存您创建的约束的引用(就像您一样),并在需要时更改它们。