NSView是用于應(yīng)用程序中渲染、打印以及處理事件的基礎(chǔ)容器。
概要
通常我們不需要直接使用NSView對(duì)象,而是使用其派生的對(duì)象或?qū)崿F(xiàn)的子類并覆蓋其方法來實(shí)現(xiàn)所需的行為。NSView(或其子類)的實(shí)例通常稱為視圖對(duì)象,或簡(jiǎn)稱為視圖。
視圖可以處理應(yīng)用程序的展示內(nèi)容及其交互。視圖對(duì)象定義了一個(gè)矩形區(qū)域,用于繪制和接收鼠標(biāo)事件。視圖還可以處理其他瑣事,包括拖動(dòng)圖標(biāo)以及與類一起使用以支持有效的滾動(dòng)。
NSView該類的大多數(shù)功能都是由AppKit自動(dòng)調(diào)用的。除非您NSView在運(yùn)行時(shí)實(shí)現(xiàn)視圖層次結(jié)構(gòu)的具體子類或與視圖層次結(jié)構(gòu)的內(nèi)容緊密聯(lián)系,否則您無需了解此類的接口。對(duì)于任何視圖,可以按原樣使用許多方法。通常使用以下方法。
-
frame返回視圖的位置和大小。 -
bounds返回視圖的內(nèi)部原點(diǎn)和大小。 -
needsDisplay視圖是否需要重繪對(duì)象。 -
window返回NSWindow包含該NSView對(duì)象的對(duì)象。 -
draw(_:)繪制視頻對(duì)象(所有子類都必須實(shí)現(xiàn)此方法,但是很少顯式調(diào)用它)。
基礎(chǔ)功能
創(chuàng)建實(shí)例
常用api:
//初始化對(duì)象
init(frame: NSRect)
// 將視圖恢復(fù)到初始狀態(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設(shè)為1.0,隱藏狀態(tài)設(shè)為false。 子類可以重寫此方法,并使用它使視圖返回其初始狀態(tài)??梢詤⒖糡ableView的復(fù)用機(jī)制
self.containerView.prepareForReuse()
}
管理視圖層次結(jié)構(gòu)
管理視圖層結(jié)構(gòu)常用api:
// 獲取當(dāng)前視圖的父視圖
var superview: NSView?
// 當(dāng)前視圖中所有子視圖
var subviews: [NSView]
// 視圖的窗口對(duì)象(如果已安裝在窗口中)
var window: NSWindow?
// 將視圖添加為指定視圖的子視圖
func addSubview(NSView)
// 在視圖的子視圖中插入一個(gè)視圖,以便將其顯示在另一個(gè)視圖的上方或下方
func addSubview(NSView, positioned: NSWindow.OrderingMode, relativeTo: NSView?)
// 從父視圖中移除
func removeFromSuperview()
修改frame
常用的api:
// 視圖的框架矩形,用于定義其在父視圖的坐標(biāo)系中的位置和大小
var frame: NSRect
// 將視圖的原點(diǎn)設(shè)置為指定點(diǎn)
func setFrameOrigin(NSPoint)
// 將視圖設(shè)置為指定的尺寸,在其父視圖內(nèi)調(diào)整其大小而不影響其坐標(biāo)系
func setFrameSize(NSSize)
// 旋轉(zhuǎn)角度(以度為單位)應(yīng)用于相對(duì)于其超級(jí)視圖坐標(biāo)系的視圖
var frameRotation: CGFloat
修改bounds
常用的api:
// 視圖的邊界矩形,表示其在自己的坐標(biāo)系中的位置和大小
var bounds: NSRect
// 將視圖的邊界矩形的原點(diǎn)設(shè)置為指定點(diǎn)
func setBoundsOrigin(NSPoint)
// 將視圖的邊界矩形的大小設(shè)置為指定的尺寸
func setBoundsSize(NSSize)
// 旋轉(zhuǎn)角度(以度為單位)
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是相對(duì)父視圖的坐標(biāo)系中的位置和大小,bounds是相對(duì)坐標(biāo)系統(tǒng)中的位置和大小。
管理視圖層
管理視圖層常用api:
// 設(shè)置為true時(shí),轉(zhuǎn)換成可支持Layer的視圖,即使用一個(gè)CALayer對(duì)象來管理呈現(xiàn)內(nèi)容,會(huì)隱式地將所有子視圖支持該屬性
var wantsLayer: Bool
// 視圖用作其后備存儲(chǔ)的核心動(dòng)畫層
var layer: CALayer?
默認(rèn)情況下,視圖是沒有創(chuàng)建layer的,也即不做任何處理時(shí),我們?cè)L問layer是為空的,當(dāng)我們?cè)O(shè)置wantsLayer為true時(shí),視圖會(huì)創(chuàng)建一個(gè)CALayer對(duì)象來管理呈現(xiàn)內(nèi)容,我們才能通過layer來修改視圖的顯示內(nèi)容,比如視圖的背景圖:
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:
// 被子類重寫以在指定的矩形內(nèi)繪制視圖的圖像
func draw(NSRect)
如果我們實(shí)現(xiàn)自己的視圖,則必須要重寫darw()方法,比如我們要實(shí)現(xiàn)一個(gè)圓形的視圖類:
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方法中,處理我們需要繪制的內(nèi)容。
小結(jié)
這里初步了解NSView的基本使用,接下來,我們會(huì)在下一節(jié),我們將會(huì)通過實(shí)現(xiàn)一個(gè)小應(yīng)用來擴(kuò)展了解。