//分欄視圖
分欄視圖( Split View)是一種用戶可拖動改變大小的區域分隔視圖控件,有左右和上下兩種風格,其對應的類是NSSplit View。中間可拖動的分隔線有3種不同寬度的樣式可以選擇。每個獨立的區域還可以繼續分隔,實現嵌套組合的復雜視圖。
SplitView類的重要屬性和方法說明如下。
1>vertical I屬性:控制NSSplit View的中間分隔區的方向,水平或垂直。
2>setPostion方法:控制分隔區在NSSplitView中的位置, position.為x方向或y方向的左
邊偏移。
3>dividerIndex:表示第幾個分格區,如果只有兩個分隔區域的話,此參數為0
4>dividerThickness方法:分隔區的大小、寬度或高度(根據vertical類型)。
sItion
方法用來設置分隔區位置
func setPosition( position: CGFloat, ofDividerAt dividerIndex: Int)
用代碼創建分欄視圖
用代碼創建分欄視圖的基本步驟如下。
(1)設置中間分隔線的方向和樣式。
(2)創建左右兩個空視圖,添加到分欄視圖。
(3)將分欄視圖添加到主視圖區。
具體代碼如下:
funccreateSplistView() {
letframeSplitView = CGRect(x: 200, y: 20, width: 200, height: 200)
letsplitView = NSSplitView(frame: frameSplitView)
//垂直方向
splitView.isVertical = true
//中間分割線的樣式
splitView.dividerStyle = .thin //NSSplitView.DividerStyle.thin
//左邊視圖
letviewLeft = NSView()
viewLeft.wantsLayer = true
viewLeft.layer?.backgroundColor = NSColor.green.cgColor
//右邊視圖
letviewRight = NSView()
viewRight.wantsLayer = true
viewRight.layer?.backgroundColor = NSColor.magenta.cgColor
//增加左右兩個視圖
splitView.addSubview(viewLeft)
splitView.addSubview(viewRight)
}
自定義分欄視圖樣式風格
除了使用分欄視圖的dividerStyle來設置不同顯示外觀以外,還可以使用自定義的子類來控
制分隔區divider視圖的顏色,甚至直接繪制divider的樣式外觀。
(1)只修改divider的顏色。dividerColor是只讀屬性,通過NSSplit View子類重置divider Color
的顏色即可。
(2)重繪外觀。通過分欄視圖子類實現draw Divider方法即可。下面的代碼重繪了divider,,
做了一個圓角矩形的圖形,使用黃色填充,藍色作為邊框的顏色,效果如圖432右邊所示。
classSplistView: NSSplitView {
/****
只修改 divider的顏色。 dividerColor是只讀屬性,通過 NSSplit View子類重置 divider Color
的顏色即可
**/
overridevardividerColor: NSColor{
returnNSColor.red
}
/****
重繪外觀。通過分欄視圖子類實現 drawDivider方法即可
下面的代碼重繪了 divider,做了一個圓角矩形的圖形,使用黃色填充,藍色作為邊框的顏色
**/
overridefuncdrawDivider(in rect: NSRect) {
letrectDivider = rect.insetBy(dx: 1, dy: 1)
letpath = NSBezierPath(roundedRect: rectDivider, xRadius: 3, yRadius: 3)
NSColor.blue.setStroke()
path.stroke()
NSColor.yellow.setFill()
path.fill()
}
}
分欄視圖中的子視圖控制
分欄視圖的子視圖行為通過 NSSplit View Delegate協議接口來實現控制。
(1)視圖Size變化通知如下。
func splitviewwillResizeSubviews( notification: Notification
func splitviewDidResizeSubviews( notification: Notification)
(2)是否允許拉伸子視圖。子視圖默認是允許拉伸的,如果需要禁止某個子視圖拉伸,則通過下面接口對相關的 subview返回 false禁止。
func splitview( splitview: NSSplitview, canCollapseSubview subview: NSView)->Bool
(3)調整各個子視圖。當分欄視圖大小發生變化時調用下面協議接口。可以在這個接口中調整各個子視圖的大小,調整的原則是要滿足子視圖fame之和再加上分隔線 divider的fram等於分欄視圖的 frame。
funcsplitView(_splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize)
默認情況下調用分欄視圖的 adjustSubviews來調整各個子視圖的大小
(4)關閉子視圖時是否允許隱藏分隔線divider,當通過拉伸某個子視圖將其隱藏時,是否同時隱藏分隔線 divider
funcsplitView(_splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool
(5)可拉伸的視圖區間范圍規定了通過分隔線 divider可以拉伸的視圖區域范圍。對於左邊的垂直方向的分欄視圖來說,分別可以通過下面兩個協議方法約定向左邊和向右邊拉伸的范圍,如Max和Min代表的距離。默認的Min為0,Max為分欄視圖的寬度
當向左拖動分隔線時, divider與分欄視圖左邊距離小於Min時,左邊子視圖隱藏關閉,即divider自動移動到最左邊;當向右拖動分隔線時, divider與分欄視圖右邊距離大於Max時,右邊子視圖隱藏關閉,即 divider自動移動到最右邊。
下面為實現NSSplitViewDelegate的方法
//實現NSSplitViewDelegate協議方法實現分欄視圖控制的例子
extensionViewController: NSSplitViewDelegate {
//只允許左邊視圖拉伸移動
funcsplitView(_splitView: NSSplitView, canCollapseSubview subview: NSView) -> Bool {
ifsubview == splitView.subviews[0] {
returntrue
}
returnfalse
}
//向左移動拉伸距離最小為30
funcsplitView(_splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
return30
}
//向右移動拉伸最大值為100
funcsplitView(_splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
return100
}
//允許調整子視圖
funcsplitView(_splitView: NSSplitView, shouldAdjustSizeOfSubview view: NSView) -> Bool {
returntrue
}
//調整子視圖大小
funcsplitView(_splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize) {
}
//允許拉伸移動子視圖最小化后隱藏分割線
funcsplitView(_splitView: NSSplitView, shouldHideDividerAt dividerIndex: Int) -> Bool {
returntrue
}
//視圖Size變化的通知
funcsplitViewDidResizeSubviews(_notification: Notification) {
}
funcsplitViewWillResizeSubviews(_notification: Notification) {
}
}
分欄子視圖的隱藏和顯示
//leftViewWidth變量用來記憶關閉前分割線divider的位置
varleftViewWidth: CGFloat = 0
letsplitView: NSSplitView = {
letframeSplitView = CGRect(x: 200, y: 20, width: 200, height: 200)
letsplitView = NSSplitView(frame: frameSplitView)
//垂直方向
splitView.isVertical = true
//中間分割線的樣式
splitView.dividerStyle = .thin //NSSplitView.DividerStyle.thin
//左邊視圖
letviewLeft = NSView()
viewLeft.wantsLayer = true
viewLeft.layer?.backgroundColor = NSColor.green.cgColor
//右邊視圖
letviewRight = NSView()
viewRight.wantsLayer = true
viewRight.layer?.backgroundColor = NSColor.magenta.cgColor
//增加左右兩個視圖
splitView.addSubview(viewLeft)
splitView.addSubview(viewRight)
returnsplitView
}()
//添加一個按鈕,此方法作為按鈕的點擊事件
@objcfunctogglepanel(_sender: NSButton) {
letsplitViewItem = splitView.arrangedSubviews
//獲取左邊自視圖
letleftView = splitViewItem[0]
//判斷左邊子視圖是否已經隱藏
ifsplitView.isSubviewCollapsed(leftView) {
splitView.setPosition(leftViewWidth, ofDividerAt: 0)
leftView.isHidden = false
} else{
leftViewWidth = leftView.frame.size.width
splitView.setPosition(0, ofDividerAt: 0)
leftView.isHidden = true
}
splitView.adjustSubviews()
}