2015-05-05 2 views
42

Я новичок в автомаркете. Я выполнил весь свой проект из xib-файла, но теперь у меня возникла проблема, когда я должен программно обновлять высоту представления. Я пробовал ниже, но теперь работаю.Программно программируется ограничение по высоте

[[self view] addConstraint:[NSLayoutConstraint constraintWithItem:loginContainer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:loginFrame.size.height]]; 

В консоли это показывает

Unable to simultaneously satisfy constraints. 
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x78724530 V:[UIView:0x790cdfb0(170)]>", 
    "<NSLayoutConstraint:0x787da210 V:[UIView:0x790cdfb0(400)]>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x78724530 V:[UIView:0x790cdfb0(170)]> 

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. 
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 
+4

Вместо добавления совершенно новое ограничение, то почему бы не просто обновите существующий? Создайте IBOutlet для существующего ограничения и измените значение 'constant'. –

+2

Вы должны сделать IBOutlet для ограничения высоты, которое вы сделали в IB, и изменить его свойство 'constant' в коде. – rdelmar

+0

этот 'loginContainer' является подзором представления, которое загружается из' [NSBundle mainBundle] loadNibName: 'как я могу создать IBOutlet здесь? –

ответ

90

Вместо добавления нового ограничения, вам необходимо изменить константу на существующем ограничении.

Используйте IBOutlet для подключения к ограничению в Interface Builder:

@property (nonatomic, weak) NSLayoutConstraint *heightConstraint; 

Затем, когда вам нужно установить его программно, просто установить постоянное свойство на ограничение:

heightConstraint.constant = 100; 

ИЛИ

Если вы не можете получить доступ к nib в Interface Builder, найдите ограничение в коде:

NSLayoutConstraint *heightConstraint; 
for (NSLayoutConstraint *constraint in myView.constraints) { 
    if (constraint.firstAttribute == NSLayoutAttributeHeight) { 
     heightConstraint = constraint; 
     break; 
    } 
} 
heightConstraint.constant = 100; 

И Swift:

if let constraint = (myView.constraints.filter{$0.firstAttribute == .width}.first) { 
      constraint.constant = 100.0 
     } 
+0

Я не могу создать это, потому что этот loginContainer загружается из внешнего xib-файла, который не является классом-членом класса self. –

+0

См. Мое редактирование выше. –

+0

Итак, существует ли цикл только для обновления ограничения? –

18

Чтобы получить справку о ваших высоте ограничений: Нажмите + Ctrl в ограничении и перенесите в ваш файл класса:

enter image description here

Для обновления значения ограничения:

self.heightConstraint.constant = 300; 
[self.view updateConstraints]; 
+0

Я не могу создать это, потому что этот loginContainer загружается из внешнего xib-файла, который не является классом-членом самостоятельно. –

+0

Этот xib не связан ни с одним классом? –

+0

да .. это внешний файл xib, который загружается NSbundle –

3

Давайте позвоним вашему представлению nibView. Таким образом, вы пытаетесь загрузить эту точку зрения в контроллере представления, поэтому первым, в вашем контроллере представления, вам необходимо загрузить его, как вы делаете это с:

[[NSBundle mainBundle] loadNibNamed:@"NibView" owner:self options:nil]; 

Тогда вы должны сказать nibView, что вы не нужно преобразовать маски автоматического изменения Into ограничений, делая

nibView.translatesAutoresizingMaskIntoConstraints = NO; 

Затем, вы можете добавить свои ограничения

NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:nibView 
                        attribute:NSLayoutAttributeHeight 
                        relatedBy:NSLayoutRelationEqual 
                        toItem:nil 
                        attribute:NSLayoutAttributeNotAnAttribute 
                       multiplier:1.0 
                        constant:yourValue]; 

И, наконец, просто добавить его к представлению ограничений:

[self.view addConstraint:heightConstraint]; 

Возможно, вам также потребуется добавить ограничение ширины.

2

Более гибкий способ использования этого быстрое расширение:

extension UIView {  

    func updateConstraint(attribute: NSLayoutAttribute, constant: CGFloat) -> Void { 
     if let constraint = (self.constraints.filter{$0.firstAttribute == attribute}.first) { 
      constraint.constant = constant 
      self.layoutIfNeeded() 
     } 
    } 
} 

Как использовать это расширение вида для обновления постоянной величины существующих ограничений:

// to update height constant 
testView.updateConstraint(attribute: NSLayoutAttribute.height, constant: 20.0) 


// to update width constant 
testView.updateConstraint(attribute: NSLayoutAttribute.width, constant: 20.0) 
Смежные вопросы