Objective-C Mac应用代码创建NSLayoutConstraint导致contentView异常缩放问题
问题原因&解决方案
核心错误1:错误修改了NSWindow contentView的自动布局标识
NSWindow的contentView是系统负责管理的根视图,它的尺寸默认和窗口绑定,由系统自动生成
NSAutoresizingMaskLayoutConstraint约束保证和窗口同步。你主动将win.contentView.translatesAutoresizingMaskIntoConstraints = NO后,系统不会生成这些约束,而你又没有给contentView添加任何宽高、位置约束,布局系统无法确定它的尺寸,最终会被压缩为0,这就是你看到窗口无内容的根本原因。
正确规则:只有你自己创建的、需要添加显式约束的子视图,才需要将translatesAutoresizingMaskIntoConstraints设为NO,系统托管的父视图不需要修改这个属性。
核心错误2:子视图约束不完整,且第二版约束存在笔误
- 你的需求是顶部视图高度固定为80,必须给自定义视图添加固定高度约束,否则垂直方向只有top约束,布局系统无法确定子视图高度,会出现布局歧义。
- 你第二版工厂方法写的trailing约束存在笔误:将view的leading属性绑定到了superview的leading属性,完全没有设置trailing的关联,所以水平方向约束失效,出现反向限制父视图宽度的问题。
修正后的完整代码
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // 创建窗口 NSRect windowRect = NSMakeRect(0.0, 0.0, 900.0, 200.0); NSWindowStyleMask windowStyle = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable; NSWindow * win = [[NSWindow alloc] initWithContentRect:windowRect styleMask:windowStyle backing:NSBackingStoreBuffered defer:NO]; win.title = @"Window Made in Code"; // !!删除原代码中修改contentView translatesAutoresizingMask的错误逻辑 // 添加视图 NSView * view = [[MyView alloc] initWithFrame:NSZeroRect]; // 仅自定义的子视图需要设置该属性 view.translatesAutoresizingMaskIntoConstraints = NO; [win.contentView addSubview:view]; // 添加约束 [view.leadingAnchor constraintEqualToAnchor:win.contentView.leadingAnchor].active = YES; [view.trailingAnchor constraintEqualToAnchor:win.contentView.trailingAnchor].active = YES; [view.topAnchor constraintEqualToAnchor:win.contentView.topAnchor].active = YES; // 补加固定高度约束 [view.heightAnchor constraintEqualToConstant:80.0].active = YES; // 显示窗口 [win center]; [win makeKeyAndOrderFront:NSApp]; self.codeWindow = win; }
额外说明
你之前注释掉contentView的translatesAutoresizingMaskIntoConstraints = NO后功能正常,是符合系统规则的,只是你之前误以为所有视图加约束都要改这个属性,实际上这个属性只需要针对使用显式约束的子视图设置即可。
内容的提问来源于stack exchange,提问作者Corbell
相关产品推荐
相关产品推荐

