创建右对齐的NSView

时间:2014-09-06 06:42:19

标签: macos cocoa autolayout

我想创建一个NSView容器,以便添加的任何NSControl对象应该是右对齐的 我已经向MyCustomNSView类添加了一个方法,如下所示。目前我正在添加左对齐的按钮。

- (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 个答案:

答案 0 :(得分:2)

要通过手动定位来实现,您可以计算按钮的框架,如下所示:

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]而不是{{1} })。如果您希望所有按钮具有相同的宽度,但让系统选择自然最宽按钮的宽度,则可以使用[button(buttonWidth)]。由于按钮的默认压缩阻力优先级高于其内容拥抱优先级,因此它将选择不压缩其中任何一个的最小宽度。

如果您希望按钮彼此相距标准距离,而不是30点的固定值,则可以使用[button(==previousButton)]代替-。同样,如果您希望它们与超视图边缘成标准距离,则可以使用-(buttonSeparation)-代替--(horizontalMargin)-

相关问题