Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 移动嵌套NSSplitView的拆分器会使其向外增长_Macos_Cocoa_Autolayout_Nssplitview - Fatal编程技术网

Macos 移动嵌套NSSplitView的拆分器会使其向外增长

Macos 移动嵌套NSSplitView的拆分器会使其向外增长,macos,cocoa,autolayout,nssplitview,Macos,Cocoa,Autolayout,Nssplitview,嵌套NSSplitView实例会导致一种奇怪的行为。拖动嵌套splitView的拆分器时,可以移动父splitView的拆分器以容纳较大的子拆分器,这是拖动的副作用 下面是一个复制此问题的极简主义项目的URL。只需向右拖动最右边的拆分器,直到最左边的拆分器开始自行移动 据我所知,问题的原因是,在拖动splitView的拆分器时,添加了一个新的约束,将被拖动拆分器左侧的contentView的右边缘绑定到NSSplitView本身的左边缘。完成拖动后,将删除此约束。当拖动正在进行且拆分器受到其他面

嵌套
NSSplitView
实例会导致一种奇怪的行为。拖动嵌套splitView的拆分器时,可以移动父splitView的拆分器以容纳较大的子拆分器,这是拖动的副作用

下面是一个复制此问题的极简主义项目的URL。只需向右拖动最右边的拆分器,直到最左边的拆分器开始自行移动

据我所知,问题的原因是,在拖动splitView的拆分器时,添加了一个新的约束,将被拖动拆分器左侧的contentView的右边缘绑定到
NSSplitView
本身的左边缘。完成拖动后,将删除此约束。当拖动正在进行且拆分器受到其他面板最小宽度的约束时,此临时约束的常量值的总和超过了窗格可以调整大小的宽度,这会使NSSplitView本身变大,从而调整最外层拆分器的大小

@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]; // This call is blocking until the drag is finished
    [self removeConstraint:self.temporaryWidthConstraint];
}

@end
我曾尝试使用
NSSplitViewDelegate
约束拆分位置,但由于临时约束,在NSSplitView已经增长之后调用此委托方法。实现一个
ConstraintMinCoordinate
ConstraintMaxCoordinate
委托方法会使
NSSplitView
完全忽略面板上配置的最小宽度

此外,当拖动开始或结束时,我似乎无法通过通知或子类化
NSSplitView
获得正确的事件。在这两个事件上都有一个钩子将允许我添加一个临时约束,以确保NSSplitView不能向外扩展。即使覆盖
mouseDown:
mouseUp:
也不起作用,因为在拖动结束后,
mouseUp:
从未被调用

更新1:
我找到了一个解释,解释了为什么没有调用
mouseUp:
:这是因为拆分器的拖动是使用在
nseventtrackingrunloop模式下运行的嵌套RunLoop实现的。这就是
mouseDragged:
mouseUp:
事件被默默吞没的方式。以下是相关文档:

了解为什么不调用
mouseUp:
,是实现此问题解决方案的关键。下面是一个自定义NSSplitView子类,它可以防止在拖动拆分器时splitView向外扩展

@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]; // This call is blocking until the drag is finished
    [self removeConstraint:self.temporaryWidthConstraint];
}

@end