如何为NSStackView添加可拖动分隔线,实现三个并排视图的大小调整?
当然可以实现!在macOS上,NSStackView本身就支持添加可拖动的分隔线来调整内部视图的大小,刚好能满足你一行排列三个可调整视图的需求。下面我给你一步步拆解具体实现方式:
实现步骤
1. 配置NSStackView的基础属性
首先得确保你的NSStackView是水平方向排列(把它的orientation属性设为.horizontal),然后关键要把distribution设置为.fill或者.fillProportionally——这俩值能让内部视图有调整大小的空间,不会被固定死。另外记得设置合适的alignment(比如.centerY),保证三个视图在垂直方向对齐整齐。
2. 添加可拖动分隔线
代码实现方式
如果是用代码创建视图,你可以先把三个视图添加到stackView的排列子视图里,然后用insertDivider(at:)方法在视图之间插入可拖动的分隔线:
// 先创建三个要展示的视图 let view1 = NSView() view1.wantsLayer = true view1.layer?.backgroundColor = NSColor.systemRed.cgColor let view2 = NSView() view2.wantsLayer = true view2.layer?.backgroundColor = NSColor.systemGreen.cgColor let view3 = NSView() view3.wantsLayer = true view3.layer?.backgroundColor = NSColor.systemBlue.cgColor // 创建并配置stackView let stackView = NSStackView(views: [view1, view2, view3]) stackView.orientation = .horizontal stackView.distribution = .fillProportionally stackView.spacing = 8 // 分隔线和视图之间的间距,可根据需求调整 // 在view1和view2之间插入可拖动分隔线 stackView.insertDivider(at: 1) // 在view2和view3之间插入可拖动分隔线 stackView.insertDivider(at: 3) // 插入第一个分隔线后,子视图数量变为5,所以第二个分隔线的位置是3 // 最后把stackView添加到窗口的contentView里 view.addSubview(stackView) stackView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20), stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 20), stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20) ])
Interface Builder可视化实现
如果你习惯用IB拖控件,操作更直观:
- 拖一个NSStackView到窗口的contentView里,在Attributes Inspector里把「Orientation」设为「Horizontal」
- 把三个自定义视图拖进stackView的「Arranged Subviews」列表中
- 选中stackView,找到「Dividers」选项组:勾选「Draw Dividers」,然后把「Style」设为你想要的样式(比如Solid),同时确保「Resizable」是勾选状态——这样分隔线就自动变成可拖动的了!
3. 自定义视图的大小规则
如果希望某个视图有固定的最小/最大宽度,或者优先保持原有尺寸,可以通过调整视图的优先级约束来实现:
// 比如让view1最小宽度不小于100,且优先保持宽度 view1.setContentHuggingPriority(.defaultHigh, for: .horizontal) view1.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) view1.minWidthAnchor.constraint(greaterThanOrEqualToConstant: 100).isActive = true
这样拖动分隔线时,view1不会被压缩到100以下,另外两个视图可以灵活调整大小。
小提示
- 分隔线的默认样式是细灰线,你可以通过
NSDividerView的dividerStyle属性或者直接设置layer的背景色来自定义外观 - 如果你想手动创建分隔线,也可以直接初始化
NSDividerView(),设置isResizable = true,然后把它添加到stackView的arranged subviews里,效果和用insertDivider(at:)完全一致
这样就能完美实现你要的三个水平排列、可通过拖动分隔线调整大小的视图效果啦!
内容的提问来源于stack exchange,提问作者aneuryzm
相关产品推荐
相关产品推荐

