Подтвердить что ты не робот

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?

4b9b3361

Ответ 1

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

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 будет, конечно, нулевым, так как нет отношения к другому виду.

Ответ 2

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

http://autolayoutconstraints.com

Вот ответ на ваш вопрос, автогенерируемый инструментом

Objective-C

// 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)]];

Swift

// 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]));

Ответ 3

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

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

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

@IBOutlet weak var spaceToTopThatIDecided: NSLayoutConstraint!

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

spaceToTopThatIDecided.constant = 44

Что все!

Ответ 4

вам не нужно использовать методы 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)]];

//thats it.

Ответ 5

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

 //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]))