2014-09-06 3 views
0

Я хочу создать контейнер NSView таким образом, что любой добавленный объект NSControl должен быть выровнен по правому краю.
Я добавил метод в класс MyCustomNSView следующим образом. В настоящее время я добавляю кнопки, которые выравниваются влево.Создание выравнивания вправо NSView

- (void) _addButton:(NSString *)title withIdentifier:(NSString *)identifier { 
    NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(100 * [_buttonIdentifierList count] + 10 , 5, 70, 20)]; 

    [button setTitle:title]; 
    [button setAction:@selector(actionButtonPressed:)]; 
    [button setTarget:self]; 
    [button setIdentifier:identifier]; 
    [self addSubview:button]; 
    [_buttonIdentifierList addObject:identifier]; 
} 

Итак, какие изменения я должен внести в метод выше, чтобы он добавил объекты с правой стороны.
Я планировал сделать это математически (генерируя начало кадра, которое создавало бы правильную выровненную точку начала). Я также пробовал использовать NSLayoutConstrains, но не работал. Как это сделать, используя автоспуск?

ответ

1

Чтобы сделать это с помощью ручного позиционирования, вы бы вычислить рамки для кнопки что-то вроде этого:

NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(NSMaxX(self.bounds) - (100 * [_buttonIdentifierList count] + 10) - 70, 5, 70, 20)]; 

То есть, вы берете свой текущий расчет, который является смещением в правую сторону (от левого края) и отрицать его, чтобы сделать его смещением влево. Вы добавляете значение правого края содержащего представления, так что это смещение от правого края. Это вычислило положение X правого края кнопки, поэтому вы вычитаете ширину кнопки, чтобы получить начало кнопки, которая находится на ее левом краю.

Чтобы использовать функцию автоматической компоновки (который использует NSLayoutConstraint), вы можете сделать это:

NSButton *button = [[NSButton alloc] initWithFrame:NSZeroRect]; 

[button setTitle:title]; 
[button setAction:@selector(actionButtonPressed:)]; 
[button setTarget:self]; 
[button setIdentifier:identifier]; 
button.translatesAutoresizingMaskIntoConstraints = NO; 
[self addSubview:button]; 

__block NSButton* previousButton = nil; 
if (_buttonIdentifierList.count) 
{ 
    NSString* previousButtonIdentifier = _buttonIdentifierList.lastObject; 
    [self.subviews enumerateObjectsUsingBlock:^(NSView* subview, NSUInteger idx, BOOL *stop){ 
     if ([subview.identifier isEqualToString:previousButtonIdentifier]) 
     { 
      previousButton = (NSButton*)subview; 
      *stop = YES; 
     } 
    }]; 
} 

NSDictionary* metrics = @{ @"buttonWidth": @70, 
          @"buttonHeight": @20, 
          @"buttonSeparation": @30, 
          @"horizontalMargin": @10, 
          @"verticalMargin": @5 }; 

if (previousButton) 
{ 
    NSDictionary* views = NSDictionaryOfVariableBindings(button, previousButton); 
    NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[button(buttonWidth)]-(buttonSeparation)-[previousButton]" options:NSLayoutFormatAlignAllBaseline metrics:metrics views:views]; 
    [self addConstraints:constraints]; 
} 
else 
{ 
    NSDictionary* views = NSDictionaryOfVariableBindings(button); 
    NSArray* constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"[button(buttonWidth)]-(horizontalMargin)-|" options:0 metrics:metrics views:views]; 
    [self addConstraints:constraints]; 
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button(buttonHeight)]-(verticalMargin)-|" options:0 metrics:metrics views:views]; 
    [self addConstraints:constraints]; 
} 

[_buttonIdentifierList addObject:identifier]; 

Нахождение previousButton будет проще, если вы следить за кнопки, а не идентификаторы. Если у вас есть объект кнопки, легко получить его идентификатор, но обратное (получение объекта кнопки, когда все, что у вас есть, является идентификатором), не так просто.

Если вы хотите, чтобы кнопки имели свою естественную ширину и высоту, а не фиксированное значение, вы можете просто отказаться от тех спецификаторов ширины и высоты (то есть использовать [button], а не [button(buttonWidth)]). Если вы хотите, чтобы все кнопки имели одинаковую ширину, но пусть система выбирает ширину самой естественной кнопки, вы можете использовать [button(==previousButton)]. Поскольку приоритет сжатия по умолчанию для кнопки выше, чем приоритет обхода содержимого, он будет выбирать наименьшую ширину, которая не сжимает ни один из них.

Если вы хотите, чтобы кнопки находились на стандартном расстоянии друг от друга, а не фиксированное значение в 30 пунктов, вы можете использовать - вместо -(buttonSeparation)-. Аналогичным образом, если вы хотите, чтобы они были стандартным расстоянием от края супервизора, вы можете использовать - вместо -(horizontalMargin)- или -(verticalMargin)-.

Смежные вопросы