Custom NSWindow traffic light position

First appeared in public No.

In macOS system, the upper left corner of the App 3 control buttons are called "traffic light" because of their color, like traffic lights and reality (red (closed), yellow (minimize), green (maximize)) .

17890443-6b05c1f4518f3faa

The actual development will encounter the default position of the button can not meet the design requirements, need to adjust their positions.

However, the system does not provide a direct method to adjust their position, the development of commonly used in two ways:

Imitate system buttons
using black magic to change the button positions

The first method, to mimic the behavior of the system requires some additional work, is not considered.
The second way the workload is relatively small, just need to do some analysis work, just do it!

Look at the layout of these buttons:

17890443-b7135251617999c8

You can see them in NSTitlebarContainerView in NSTitlebarView years, and the use of automatic layout (autolayout) way.

This idea is very simple, just give it a few buttons to set constraints, you can achieve the purpose of the position change.

What timing constraints set a better arrangement? The answer is that after the completion of the initialization Window is the best time, the code is as follows:

@implementation TUINSWindow

- (instancetype)initWithContentRect:(CGRect)rect {
...
  [self relayoutWindowButtons];
...
}

- (void)relayoutWindowButtons {
    NSButton *closeButton = [self standardWindowButton:NSWindowCloseButton];
    NSButton *minButton = [self standardWindowButton:NSWindowMiniaturizeButton];
    NSButton *zoomButton = [self standardWindowButton:NSWindowZoomButton];

    NSView *titlebarView = closeButton.superview;
    closeButton.translatesAutoresizingMaskIntoConstraints = NO;
    [titlebarView addConstraints:@[
                                   [NSLayoutConstraint constraintWithItem:closeButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:titlebarView attribute:NSLayoutAttributeTop multiplier:1 constant:9],
                                   [NSLayoutConstraint constraintWithItem:closeButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:titlebarView attribute:NSLayoutAttributeLeft multiplier:1 constant:2]
                                   ]];

    minButton.translatesAutoresizingMaskIntoConstraints = NO;
    [titlebarView addConstraints:@[
                                   [NSLayoutConstraint constraintWithItem:minButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:titlebarView attribute:NSLayoutAttributeTop multiplier:1 constant:9],
                                   [NSLayoutConstraint constraintWithItem:minButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:titlebarView attribute:NSLayoutAttributeLeft multiplier:1 constant:20]
                                   ]];

    zoomButton.translatesAutoresizingMaskIntoConstraints = NO;
    [titlebarView addConstraints:@[
                                   [NSLayoutConstraint constraintWithItem:zoomButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:titlebarView attribute:NSLayoutAttributeTop multiplier:1 constant:9],
                                   [NSLayoutConstraint constraintWithItem:zoomButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:titlebarView attribute:NSLayoutAttributeLeft multiplier:1 constant:38]
                                   ]];
}

@end

TUINSWindow inherited from NSWindow, after setting a good style can be called
relayoutWindowButtons method to set up constraints.

NSWindow provided a method of system acquisition button: - (NSButton *) standardWindowButton: (NSWindowButton) b; According to previous analyzes, the parent window is a button NSTitlebarView.

Look at the results after the adjustment:

17890443-b351153ac683002d

We're done!

Secretly, I found macOS version micro-channel, micro-channel business, so they are also implemented.

If you want that, you only need to adjust the following constraints like micro-letters macOS version, in the above constraints, do not add the left constraint on it:

- (void)relayoutWindowButtons {
    NSButton *closeButton = [self standardWindowButton:NSWindowCloseButton];
    NSButton *minButton = [self standardWindowButton:NSWindowMiniaturizeButton];
    NSButton *zoomButton = [self standardWindowButton:NSWindowZoomButton];

    NSView *titlebarView = closeButton.superview;
    closeButton.translatesAutoresizingMaskIntoConstraints = NO;
    [titlebarView addConstraints:@[
                                   [NSLayoutConstraint constraintWithItem:closeButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:titlebarView attribute:NSLayoutAttributeTop multiplier:1 constant:9]
                                   ]];

    minButton.translatesAutoresizingMaskIntoConstraints = NO;
    [titlebarView addConstraints:@[
                                   [NSLayoutConstraint constraintWithItem:minButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:titlebarView attribute:NSLayoutAttributeTop multiplier:1 constant:9]
                                   ]];

    zoomButton.translatesAutoresizingMaskIntoConstraints = NO;
    [titlebarView addConstraints:@[
                                   [NSLayoutConstraint constraintWithItem:zoomButton attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:titlebarView attribute:NSLayoutAttributeTop multiplier:1 constant:9]
                                   ]];
}

Look at the results, and micro-channel compare, it is not exactly the same as the:

17890443-77be1d7a2d2c5f3e

The End, thanks for reading _

17890443-813e61866c38e31c

Guess you like

Origin blog.csdn.net/weixin_33695082/article/details/90858864