osx - Moving the splitter of a nested NSSplitView makes it grow outwardly -


nesting nssplitview instances leads strange behavior. when dragging nested splitview's splitter, parent splitview's splitter can moved accomodate larger child side-effect of dragging.

here url minimalist project reproduces problem. drag right-most splitter towards right until left-most splitter starts moving on own. http://filebin.ca/20ymcpnmtts7/nestedsplittest.zip

to understanding, cause of problem when dragging splitview's splitter, new constraint added binding right edge of contentview on left side of dragged splitter left edge of nssplitview itself. constraint removed when drag complete. while drag ongoing , splitter gets constrained minimum widths of other panels, total of temporary constraint's constant value exceeds width pane can resize , makes nssplitview grow larger, in turn resizes outermost splitter.

i have tried using nssplitviewdelegate constrain split position delegate method called after nssplitview has grown because of temporary constraint. implementing 1 of constrainmincoordinate or constrainmaxcoordinate delegate methods makes nssplitview ignore minimum widths configured on panels.

also, cannot seem proper event when drag starts or ends, either through notifications or subclassing nssplitview. having hook on both of these events allow me add temporary constraint make sure nssplitview can't grow outwardly. overriding mousedown: , mouseup: didn't work because mouseup: never got called after drag ended.

update 1: have found explanation reason mouseup: not called : because dragging of splitter implemented using nested runloop runs in nseventtrackingrunloopmode. how mousedragged: , mouseup: events swallowed silently. here relevant documentation : https://developer.apple.com/library/mac/documentation/cocoa/conceptual/eventoverview/handlingmouseevents/handlingmouseevents.html#//apple_ref/doc/uid/10000060i-ch6-sw4

understanding why mouseup: not being called key implementing solution problem. here custom nssplitview subclass prevents splitview growing outwardly when dragging splitter.

@interface nestablesplitview : nssplitview  @property(strong) nslayoutconstraint* temporarywidthconstraint;  @end  @implementation nestablesplitview  - (void)mousedown:(nsevent *)theevent {     if (!self.temporarywidthconstraint) {         self.temporarywidthconstraint = [nslayoutconstraint constraintwithitem:self attribute:nslayoutattributewidth relatedby:nslayoutrelationequal toitem:nil attribute:nslayoutattributenotanattribute multiplier:1 constant:0];     }     self.temporarywidthconstraint.constant = nswidth(self.bounds);     [self addconstraint:self.temporarywidthconstraint];     [super mousedown:theevent]; // call blocking until drag finished     [self removeconstraint:self.temporarywidthconstraint]; }  @end 

Comments