NSView是用于應用程序中渲染、打印以及處理事件的基礎容器。
概要
通常我們不需要直接使用NSView對象,而是使用其派生的對象或實現的子類并覆蓋其方法來實現所需的行為。NSView(或其子類)的實例通常稱為視圖對象,或簡稱為視圖。
視圖可以處理應用程序的展示內容及其交互。視圖對象定義了一個矩形區(qū)域,用于繪制和接收鼠標事件。視圖還可以處理其他瑣事,包括拖動圖標以及與類一起使用以支持有效的滾動。
NSView該類的大多數功能都是由AppKit自動調用的。除非您NSView在運行時實現視圖層次結構的具體子類或與視圖層次結構的內容緊密聯(lián)系,否則您無需了解此類的接口。對于任何視圖,可以按原樣使用許多方法。通常使用以下方法。
-
frame返回視圖的位置和大小。 -
bounds返回視圖的內部原點和大小。 -
needsDisplay視圖是否需要重繪對象。 -
window返回NSWindow包含該NSView對象的對象。 -
draw(_:)繪制視頻對象(所有子類都必須實現此方法,但是很少顯式調用它)。
基礎功能
創(chuàng)建實例
常用api:
//初始化對象
init(frame: NSRect)
// 將視圖恢復到初始狀態(tài),以便可以重用
func prepareForReuse()
我們可以通過init來創(chuàng)建視圖,并可以通過prepareForReuse方法來重置視圖:
lazy var containerView: NSView = {
let view = NSView(frame: NSRect(x:20, y: 20, width: 100, height: 100))
view.wantsLayer = true
view.layer?.backgroundColor = NSColor.red.cgColor
view.alphaValue = 0.5
return view
}()
private func resetView() {
// 將視圖的Alpha設為1.0,隱藏狀態(tài)設為false。 子類可以重寫此方法,并使用它使視圖返回其初始狀態(tài)。可以參考TableView的復用機制
self.containerView.prepareForReuse()
}
管理視圖層次結構
管理視圖層結構常用api:
// 獲取當前視圖的父視圖
var superview: NSView?
// 當前視圖中所有子視圖
var subviews: [NSView]
// 視圖的窗口對象(如果已安裝在窗口中)
var window: NSWindow?
// 將視圖添加為指定視圖的子視圖
func addSubview(NSView)
// 在視圖的子視圖中插入一個視圖,以便將其顯示在另一個視圖的上方或下方
func addSubview(NSView, positioned: NSWindow.OrderingMode, relativeTo: NSView?)
// 從父視圖中移除
func removeFromSuperview()
修改frame
常用的api:
// 視圖的框架矩形,用于定義其在父視圖的坐標系中的位置和大小
var frame: NSRect
// 將視圖的原點設置為指定點
func setFrameOrigin(NSPoint)
// 將視圖設置為指定的尺寸,在其父視圖內調整其大小而不影響其坐標系
func setFrameSize(NSSize)
// 旋轉角度(以度為單位)應用于相對于其超級視圖坐標系的視圖
var frameRotation: CGFloat
修改bounds
常用的api:
// 視圖的邊界矩形,表示其在自己的坐標系中的位置和大小
var bounds: NSRect
// 將視圖的邊界矩形的原點設置為指定點
func setBoundsOrigin(NSPoint)
// 將視圖的邊界矩形的大小設置為指定的尺寸
func setBoundsSize(NSSize)
// 旋轉角度(以度為單位)
var boundsRotation: CGFloat
通過boundsRotation來圖一朵小????:
for i in 1...18 {
let v = NSView(frame: NSRect(x:60, y: 60, width: 100, height: 100))
v.wantsLayer = true
v.alphaValue = 0.5
v.layer?.backgroundColor = NSColor.red.cgColor
v.boundsRotation = CGFloat(i * 10)
view.addSubview(v)
}
frame 與 bounds 區(qū)別
frame是相對父視圖的坐標系中的位置和大小,bounds是相對坐標系統(tǒng)中的位置和大小。
管理視圖層
管理視圖層常用api:
// 設置為true時,轉換成可支持Layer的視圖,即使用一個CALayer對象來管理呈現內容,會隱式地將所有子視圖支持該屬性
var wantsLayer: Bool
// 視圖用作其后備存儲的核心動畫層
var layer: CALayer?
默認情況下,視圖是沒有創(chuàng)建layer的,也即不做任何處理時,我們訪問layer是為空的,當我們設置wantsLayer為true時,視圖會創(chuàng)建一個CALayer對象來管理呈現內容,我們才能通過layer來修改視圖的顯示內容,比如視圖的背景圖:
lazy var containerView: NSView = {
let view = NSView(frame: NSRect(x:20, y: 20, width: 100, height: 100))
view.wantsLayer = true
view.layer?.backgroundColor = NSColor.red.cgColor
return view
}()
繪制視圖
繪制視圖常用api:
// 被子類重寫以在指定的矩形內繪制視圖的圖像
func draw(NSRect)
如果我們實現自己的視圖,則必須要重寫darw()方法,比如我們要實現一個圓形的視圖類:
class CircleView: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
setCornerRadius(dirtyRect.size)
}
override func setFrameSize(_ newSize: NSSize) {
super.setFrameSize(newSize)
setCornerRadius(newSize)
}
override func setBoundsSize(_ newSize: NSSize) {
super.setBoundsSize(newSize)
setCornerRadius(newSize)
}
private func setCornerRadius(_ size: NSSize) {
self.wantsLayer = true
self.layer?.cornerRadius = size.width / 2;
self.layer?.masksToBounds = true
}
}
我們需要在darw方法中,處理我們需要繪制的內容。
小結
這里初步了解NSView的基本使用,接下來,我們會在下一節(jié),我們將會通過實現一個小應用來擴展了解。