objective-cmacosautolayoutnsviewnssplitview

Prevent breaking constraint on collapsable NSSplitView


I have a NSSplitView which contains a NSSearchField. It looks like this:

Splitview example

I've created the NSSearchField with the following code:

- (void) applicationDidFinishLaunching: (NSNotification *) aNotification
{
    searchField = [[NSSearchField alloc] init];
    searchField.translatesAutoresizingMaskIntoConstraints = NO;
    [leftView addSubview: searchField];
    [searchField.leadingAnchor constraintEqualToAnchor: leftView.leadingAnchor
                                              constant: 1.0f].active = YES;
    [searchField.trailingAnchor constraintEqualToAnchor: leftView.trailingAnchor
                                               constant: -1.0f].active = YES;
    [searchField.topAnchor constraintEqualToAnchor: leftView.topAnchor
                                          constant: 1.0f].active = YES;
    [searchField.heightAnchor constraintEqualToConstant: 22.0f].active = YES;
}

This works fine and I can resize the splitter with no problem.

If I however, add the following NSSplitViewDelegate method (trying to make the left side completely collapsable):

- (CGFloat)splitView:(NSSplitView *)splitView
constrainMinCoordinate:(CGFloat)proposedMinimumPosition
         ofSubviewAt:(NSInteger)dividerIndex
{
    if(0 == dividerIndex)
    {
        return 0;
    }

    return proposedMinimumPosition;
}

Now if I resize the splitter so that the left view is collapsed, I get a constraint violation.

AnchorTest[57668:1656122] [Layout] Unable to simultaneously satisfy constraints:
(
    "<NSAutoresizingMaskLayoutConstraint:0x604000084c40 h=--& v=--& NSView:0x60c000120b40.width == 0.5   (active)>",
    "<NSLayoutConstraint:0x60c0000822b0 H:|-(1)-[NSSearchField:0x100412290]   (active, names: '|':NSView:0x60c000120b40 )>",
    "<NSLayoutConstraint:0x60c000085f50 NSSearchField:0x100412290.trailing == NSView:0x60c000120b40.trailing   (active)>"
)

Which makes sense.. Obviously the search field leading/trailing anchors cannot be offset by -1 and if I remove the offset, the constraints have no issues.

The problem is that I want the left/right offset. There must be a way to do this via AutoLayout, but I'm not able to figure it out. Does anyone know how one would properly do this?


Solution

  • Dragging the divider to the end is not the same as collapsing. Return the minimal useable size from constrainMinCoordinate and implement splitView:canCollapseSubview:.