秦人不暇自哀,而后人哀之;后人哀之而不鑒之,亦使后人而復(fù)哀后人也
在便捷的
網(wǎng)絡(luò)時(shí)代學(xué)習(xí)
,更注重
對(duì)基礎(chǔ)知識(shí)的借與鑒。在macOS 開發(fā)基礎(chǔ)教程視頻課程的NSView章節(jié)中,解釋了關(guān)于視圖的frame
和bounds
的坐標(biāo)參照系統(tǒng)
,限于授課經(jīng)驗(yàn)
與課程時(shí)間
,感覺對(duì)NSView的bounds屬性,表述的不夠深入,希望通過本文幫助觀看課程的同學(xué)
加深對(duì)bounds的理解,并通過實(shí)例運(yùn)用
,體會(huì)在NSView
中bounds
的真正價(jià)值。
關(guān)于視圖NSView的frame
和bounds
的概念,我們就不再介紹了,(課程的視頻中有圖例講解
,網(wǎng)上也有相關(guān)資料),這里只重點(diǎn)突出視頻教程中的闡述的兩個(gè)點(diǎn):
- frame : 相對(duì)父控件的坐標(biāo)系統(tǒng)的描述
- bounds:相對(duì)NSView自身坐標(biāo)系統(tǒng)的描述
上面這兩點(diǎn)如果從字面的含義
理解起來可能會(huì)覺得有些抽象
,為了便于具體說明
,我們打個(gè)比方
,將frame想象成為一個(gè)相框,它的作用僅僅是告訴父控件
自己需要占據(jù)的位置
和尺寸
(嘿!父控件,我需要在你的坐標(biāo)系統(tǒng)
中的占據(jù)這個(gè)frame.origin
位置,尺寸是frame.size
的區(qū)域),這樣以來,父控件在布局的時(shí)候
,就會(huì)知道如何擺放它內(nèi)部的所有控件
了。
視圖NSView
里的各種內(nèi)容(subViews)
,我們可以想象成為各種相片,它們既可以擺放在相框的(frame)內(nèi)部
,也可以擺放在相框的(frame)外部
。這正如你在房間的墻上(父控件)
里放置了一個(gè)有相框壁畫(NSView)
。
為了防止壁畫(NSView)
蒙塵,你將整個(gè)壁畫(NSView)
都遮蓋保護(hù)起來。可是一旦遮蓋起來,你發(fā)現(xiàn)自己都無法觀看了,這時(shí)候你想到了一個(gè)聰明的辦法
:在遮蓋上開啟一個(gè)矩形的窗口
,透過這個(gè)窗口
,就可以看到遮蓋下面的壁畫(NSView)
了,如你所料:這個(gè)矩形的窗口
,就是bounds
通過bounds
,我們就可以看到NSView
內(nèi)部所展示的內(nèi)容。如果bounds比較小(就像你在遮蓋上開了一個(gè)小小的窗口)
,可以通過移動(dòng)
bounds位置,來展示NSView的各個(gè)區(qū)域內(nèi)容
。這樣bounds
就成為了我們對(duì)NSView
的觀景窗~
如果現(xiàn)在你已經(jīng)理解
了bounds,那么對(duì)于ScrollView的是如何實(shí)現(xiàn)滑動(dòng)展示
其內(nèi)部視圖內(nèi)容,就不會(huì)覺得奇怪
了。
下面我們通過一個(gè)示例來加深對(duì)bounds的理解和使用
-
創(chuàng)建一個(gè)Mac application 項(xiàng)目工程,從控件庫(kù)中拖動(dòng)一個(gè)customView到ViewController中,并搭建UI界面大致如下:
UI界面 在customView中添加隨意幾個(gè)box視圖,并設(shè)置顏色(為了觀看效果)。
添加自定義類CustomScrollView.swift文件(繼承自NSView)來管理customView控件
在Storyboard中設(shè)置customView的類屬性為:CustomScrollView
- 實(shí)現(xiàn)CustomScrollView.swift的代碼:
import Cocoa
class CustomScrollView: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
NSColor.lightGray.set()
NSRectFill(dirtyRect)
// Drawing code here.
}
override func awakeFromNib() {
super.awakeFromNib()
let pan = NSPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
addGestureRecognizer(pan)
}
// 移動(dòng)鼠標(biāo)時(shí),修改視圖的bounds屬性,即可實(shí)現(xiàn)scroll效果
func handlePanGesture(_ panGesture : NSPanGestureRecognizer){
let transPoint = panGesture.translation(in: self)
bounds.origin.x -= transPoint.x
bounds.origin.y -= transPoint.y
panGesture .setTranslation(NSZeroPoint, in: self)
}
}
-
最終運(yùn)行效果:
運(yùn)行效果
結(jié)束語
我們通過修改
一個(gè)NSView
的bounds
,自己實(shí)現(xiàn)了一個(gè)
類似的ScrollView,希望通過本文
對(duì)視頻課程的補(bǔ)充
,對(duì)你理解bounds
屬性有所助益,并同時(shí)希望對(duì)ScrollView
的實(shí)現(xiàn)機(jī)制,你也能有比從前更多
一點(diǎn)的掌握了。
謝謝觀看,祝課程學(xué)習(xí)愉快~