Nslayoutconstraints и установка ширины/высоты представления динамически

у меня есть вопрос о настройке размера представления, к которому я применяю некоторые ограничения макета.
Как определить размер представления без определения его рамки?

Я пытаюсь создать вид, который имеет фиксированную высоту и имеет начало координат в начале экрана. Он заполняет ширину вида, так что при вращении устройства вид распространяется на ширину экрана. Это все, что у меня есть...

self.containerView = [[HitTestContainerView alloc] init];
[self.containerView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:self.containerView];

NSDictionary *viewsDictionary = @{@"view":self.containerView};
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[view]-250-|" options:0 metrics:nil views:viewsDictionary];
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:viewsDictionary];
[self.view addConstraints:verticalConstraints];
[self.view addConstraints:horizontalConstraints];

проблема в том, что я ничего не могу получить чтобы появиться на экране, если я не установил кадр этого containerView. Каков правильный способ сделать это без использования Interface Builder?

5 ответов


чтобы определить высоту и ширину вида с помощью ограничений компоновки, вы, э-э, определяете высоту и ширину вида с помощью ограничений компоновки. Например, вы уже говорите:

NSArray *verticalConstraints = 
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[view]-250-|" 
    options:0 metrics:nil views:viewsDictionary];

так что вы можете просто изменить это на:

NSArray *verticalConstraints = 
[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(50)-[view(40)]" 
    options:0 metrics:nil views:viewsDictionary];

теперь вид будет 50 пикселей от верхней части его супервизора и 40 пикселей высотой.

в качестве альтернативы вы можете использовать constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant: чтобы установить ограничение высоты;toItem будет ноль, конечно, так как нет отношение к другому мнению.


Я написал небольшой инструмент, который поможет вам в этом:

http://autolayoutconstraints.com

вот ответ на ваш вопрос автоматически с помощью инструмента

С

// align view from the left and right
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[view]-10-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)]];

// width constraint
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[view(==250)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)]];

// height constraint
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[view(==50)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(view)]];

Свифт

// align view from the left and right
self.containerView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[view]-10-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view": view]));

// width constraint
self.containerView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[view(==250)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view": view]));

// height constraint
self.containerView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[view(==50)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view": view]));

лучше поздно, чем никогда...

для раскадровки, IB и Swift:

Just control-перетащите ограничение, как и любой другой элемент управления в viewController

@IBOutlet weak var spaceToTopThatIDecided: NSLayoutConstraint!

затем измените его просто:

spaceToTopThatIDecided.constant = 44

вот и все!


вам не нужно использовать addConstraints: () методы

- (void)addConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_MAC(10_7);

/ / этот метод устарел и его следует избегать.  Вместо этого задайте для активного свойства NSLayoutConstraint значение YES.

- (void)addConstraints:(NSArray *)constraints NS_AVAILABLE_MAC(10_7);   

/ / этот метод устарел и его следует избегать.  Вместо этого используйте

+[NSLayoutConstraint activateConstraints:].

// так нужно использовать

+ (void)activateConstraints:(NSArray *)constraints NS_AVAILABLE(10_10, 8_0);

// затем установить как

NSView *view,*containerView;
view =//superview
containerView=//subview
[view addSubview:containerView];

// добавление ограничений

[containerView setTranslatesAutoresizingMaskIntoConstraints:NO];

/ / об этом читайте Из Apple документация

/ / затем добавьте ограничения, такие как

[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[view]-50-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(containerView)]];
[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(containerView)]];

// вот и все.


Swift 4: Вы можете управлять шириной и высотой, в дополнение к лидирующему, трейлингу и верхнему и нижнему пространству только с помощью следующих 2 опций

 //1 . left and right spacing
    theContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-16-[view]-16-|", options:NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":nibView]))

 //2. top and bottom spacing
    theContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-16-[view]-16-|", options:NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":nibView]))

или чтобы быть более конкретным и иметь отдельные ограничения для W, H, левого интервала, верхнего интервала, вы можете сделать, как показано ниже

 //left only spacing
        theContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-16-[view]", options:NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":nibView]))

//top only spacing
        theContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-16-[view]", options:NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":nibView]))

//width
        theContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[view(==130)]", options:NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":nibView]))

//height
        theContentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[view(==100)]", options:NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["view":nibView]))