【问题标题】:Subview of custom NSView is resizing itself to fit within its superview自定义 NSView 的子视图正在调整自身大小以适应其父视图
【发布时间】:2010-03-23 03:43:33
【问题描述】:

我有一个包含子视图的自定义 NSView——为了解决这个问题,顶层视图只是充当容器并自动调整大小以适应窗口。它的子视图从窗口边缘绘制一个 10 像素插入的矩形,底部除外,它应该被窗口剪裁,直到它被调整大小以显示整个矩形。但是,它并没有按照我的意图运行,而是在其父视图的高度小于它的高度时缩小矩形的高度。我该如何避免这种情况并让它保持在适当的高度,而不是在超级视图较小时被剪裁?

父视图的实现代码为:

- (id)initWithFrame:(NSRect)frameRect {
    self = [super initWithFrame:frameRect];
    if (self) {
        subView = [[SubView alloc] initWithFrame:frameRect];
    }
    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    [[NSColor grayColor] set];
    [subView setFrame:NSMakeRect(10, 10, dirtyRect.size.width - 20, 500)];
    [self addSubview:subView];
}

- (BOOL)isFlipped {
    return YES;
}

而子视图只是:

- (void)drawRect:(NSRect)dirtyRect {
    [[NSColor blackColor] set];
    [NSBezierPath strokeRect:dirtyRect];
}

- (BOOL)isFlipped {
    return YES;
}

【问题讨论】:

    标签: objective-c cocoa nsview


    【解决方案1】:

    正如ericgorr 指出的那样,autoResizingMask 应该负责调整大小问题。

    但是,我注意到您在drawRect 中添加了您的子视图,这不是执行此操作的正确位置。 drawRect 在程序的生命周期内被多次调用,但 addSubview: 只需要(并且只有应该)被调用一次,如下所示:

    - (id)initWithFrame:(NSRect)frameRect {
        self = [super initWithFrame:frameRect];
        if (self) {
            subView = [[SubView alloc] initWithFrame:frameRect];
            [self addSubview:subView]; // this view now owns subView ...
            [subView release];         // ... so we can release our copy
        }
        return self; 
    } 
    
    - (void)drawRect:(NSRect)dirtyRect { 
        [[NSColor grayColor] set]; 
        [subView setFrame:NSMakeRect(10, 10, [self bounds].size.width - 20, 500)];
    } 
    

    还要注意使用[self bounds] 而不是dirtyRectdirtyRect 是一个描述需要重绘的区域的矩形。这并不总是您的视图的整个边界矩形。另一方面,[self bounds] 将始终代表您的视图的整个边界,无论哪个部分被重绘。

    【讨论】:

    • 正如我在回复 ericgorr 的回答中指出的那样,我无法让它与 autoResizingMask 一起使用。关于addSubview: 的位置和使用[self bounds],不过,谢谢你告诉我!这是有道理的。
    • 现在我已经在子视图中实现了[self bounds] 而不是dirtyRect 的使用,它可以工作,鉴于您对dirtyRect 描述该区域的解释,这是有道理的重绘。所以,谢谢!
    【解决方案2】:

    您的子视图很可能有一个自动调整大小的掩码。你可以通过调用 -setAutoresizingMask: 和 NSViewNotSizable 来清除它。

    如果超级视图不应该调整其任何子视图的大小,您可以考虑使用 -setAutoresizesSubviews:

    【讨论】:

    • 我已经尝试了 -setAutoresizingMask: 在父视图和子视图上都使用 NSViewNotSizeable,在父视图上使用 -setAutoresizesSubviews,但无济于事。它与我尝试过的所有组合的行为方式相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多