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

Получение существующего NSLayoutConstraint для ширины?

Я пытаюсь анимировать элемент управления в Cocoa с автоматической компоновкой.

Теперь я могу установить [[constraint animator] setConstant:newWidth];, который работает. Но как я могу получить правильное ограничение?

С [self constraints] вы можете получить все ограничения, и в этом случае я могу просто выбрать constraints[0], но порядок ограничений может отличаться.

Как я могу быть уверен, что у меня всегда есть правильное ограничение? Ограничения задаются в Interface Builder. Я видел, что вы можете добавить к нему IBOutlet, но это не кажется необходимым.


Мое решение

Спасибо, он отлично поработал. Я написал небольшую категорию.


NSView + NSLayoutConstraintFilter.h

#import <Cocoa/Cocoa.h>

@interface NSView (NSLayoutConstraintFilter)
- (NSLayoutConstraint *)constraintForAttribute:(NSLayoutAttribute)attribute;
- (NSArray *)constaintsForAttribute:(NSLayoutAttribute)attribute;
@end

NSView + NSLayoutConstraintFilter.m

#import "NSView+NSLayoutConstraintFilter.h"

@implementation NSView (NSLayoutConstraintFilter)

- (NSArray *)constaintsForAttribute:(NSLayoutAttribute)attribute {
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", attribute];
    NSArray *filteredArray = [[self constraints] filteredArrayUsingPredicate:predicate];

    return filteredArray;
}

- (NSLayoutConstraint *)constraintForAttribute:(NSLayoutAttribute)attribute {
    NSArray *constraints = [self constaintsForAttribute:attribute];

    if (constraints.count) {
        return constraints[0];
    }

    return nil;
}

@end
4b9b3361

Ответ 1

Каждое противопоставление имеет атрибут [constraint firstAttribute] Он возвращает перечисление NSLayoutAttribute

typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
    NSLayoutAttributeLeft = 1,
    NSLayoutAttributeRight,
    NSLayoutAttributeTop,
    NSLayoutAttributeBottom,
    NSLayoutAttributeLeading,
    NSLayoutAttributeTrailing,
    NSLayoutAttributeWidth,
    NSLayoutAttributeHeight,
    NSLayoutAttributeCenterX,
    NSLayoutAttributeCenterY,
    NSLayoutAttributeBaseline,

    NSLayoutAttributeNotAnAttribute = 0
};

чтобы вы могли проверить NSLayoutAttributeWidth для ширины.

Пример кода:

NSArray constraints = [self constraints];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", NSLayoutAttributeWidth];
NSArray *filteredArray = [constraints filteredArrayUsingPredicate:predicate];
if(filteredArray.count == 0){
      return nil;
}
NSLayoutConstraint *constraint =  [constraints objectAtIndex:0];

Ответ 2

Вот версия с быстрым 3, протестированная на Xcode 8.2.1 и macOS 10.12.2.

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

let cons = signInButton.constraints.filter {
    $0.firstAttribute == NSLayoutAttribute.width || $0.firstAttribute == NSLayoutAttribute.height /// or other from `NSLayoutAttribute`
}
// do something with the constraints array, e.g.
NSLayoutConstraint.deactivate(cons)