Mac OS X開(kāi)發(fā) —— NSSplitView&NSSplitViewController

直入主題续挟,本文來(lái)講一講關(guān)于Mac上最常用的控件之一NSSplitView的一些相關(guān)問(wèn)題。

首先侥衬,NSSplitView作為分隔內(nèi)容的一個(gè)視圖诗祸,支持拖拽改變分隔區(qū)域的大小,支持塌陷(collaps)浇冰。但是NSSplitView在與autolayout混合使用的時(shí)候會(huì)有很多問(wèn)題贬媒。

通常我們需要類似QQ的效果,我們需要的是當(dāng)我們拉伸整個(gè)視圖的時(shí)候肘习,某一個(gè)子視圖會(huì)被拉伸际乘,而其他的視圖保持原有大小,當(dāng)我們拉伸整個(gè)視圖的時(shí)候漂佩,我們同樣經(jīng)常需要壓縮某一個(gè)視圖而保持其他視圖的尺寸脖含,當(dāng)被壓縮的子視圖達(dá)到我們?cè)O(shè)定的最小尺寸的時(shí)候,我們會(huì)尋找第二低HoldingPriority的視圖進(jìn)行壓縮投蝉,直到所有的視圖都達(dá)到我們?cè)O(shè)定的最小尺寸养葵,或是整個(gè)窗口已經(jīng)達(dá)到最小尺寸為止。

問(wèn)題一:
當(dāng)我們使用autolayout來(lái)控制splitView的每個(gè)子視圖的尺寸的時(shí)候瘩缆,我們會(huì)發(fā)現(xiàn)一個(gè)現(xiàn)象如圖:

error.jpg

鼠標(biāo)位置明明已經(jīng)達(dá)到autolayout最大約束了关拒,但是還是顯示向右可拖拽的單向箭頭。控制箭頭的類型要通過(guò)實(shí)現(xiàn)NSSplitViewDelegate下的
optional func splitView(splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat
optional func splitView(splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat
來(lái)實(shí)現(xiàn)着绊。但是谐算,當(dāng)我們?cè)贜SSplitViewController直接Override以上兩個(gè)方法的話,會(huì)直接crash归露,所以我采用的方法是生命一個(gè)代理對(duì)象洲脂,然后把代理對(duì)象設(shè)置成splitView的delegate,這樣在override上邊兩個(gè)方法就可以正常執(zhí)行了剧包,但是恐锦,鼠標(biāo)類型是對(duì)了,又產(chǎn)生了其他問(wèn)題疆液。

問(wèn)題二:
本來(lái)一铅,我是使用autolayout來(lái)控制各個(gè)子視圖的尺寸的,但是使用autolayout約束字視圖大小時(shí)如果和代理方法設(shè)置的constrainMaxCoordinate堕油、constrainMinCoordinate沖突的話會(huì)報(bào)錯(cuò)馅闽,所以保險(xiǎn)起見(jiàn),我們最好移除所有和這兩個(gè)屬性相關(guān)的約束馍迄。我本來(lái)以為,這樣的話我的問(wèn)題就解決了局骤。但是攀圈,too young too simple。

問(wèn)題三:
optional func splitView(splitView: NSSplitView, constrainMinCoordinate proposedMinimumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat
optional func splitView(splitView: NSSplitView, constrainMaxCoordinate proposedMaximumPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat
optional func splitView(splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize)
func splitView(splitView: NSSplitView, shouldAdjustSizeOfSubview view: NSView) -> Bool
如果設(shè)置了NSSplitView實(shí)例對(duì)象的delegate峦甩,并且實(shí)現(xiàn)了以上四個(gè)代理方法中某一個(gè)赘来,則splitView的每個(gè)subview的HoldingPriority會(huì)失效,也就是在拉伸或者壓縮整個(gè)splitview的時(shí)候HoldingPriority比較低的subview不會(huì)被優(yōu)先拉伸凯傲,而是以默認(rèn)情況下按照所占比例整體拉伸相應(yīng)的距離犬辰,這個(gè)反饋太shit了。在沒(méi)有其他辦法的情況下冰单,我們不得不硬著頭皮實(shí)現(xiàn)上邊四個(gè)方法中的倒數(shù)第二個(gè)幌缝,來(lái)純手動(dòng)計(jì)算不同情況下各個(gè)子視圖的大小,這個(gè)地方寫(xiě)起來(lái)是非常麻煩的诫欠。下邊提供一個(gè)范例:
func splitView(splitView: NSSplitView, resizeSubviewsWithOldSize oldSize: NSSize) { // 字視圖通常分為兩個(gè)部分涵卵,內(nèi)容子視圖和分割線視圖(分割線視圖也是有尺寸的,所以要計(jì)算在內(nèi)) let dividerThickness = splitView.dividerThickness // 如果當(dāng)前的splitView的寬度和之前的寬度沒(méi)有變化荒叼,證明我們沒(méi)有拉伸或者壓縮splitView轿偎,這樣我們就可以調(diào)用adjustSubviews()讓系統(tǒng)自己設(shè)置divider的位置,我們就不用操心這種情況下的子視圖的大小和位置了被廓,但是坏晦,如果對(duì)splitView進(jìn)行了拉伸或者壓縮,這個(gè)時(shí)候我們?cè)趯?shí)現(xiàn)了某個(gè)代理方法之后就不得不自己去計(jì)算各種情況下每個(gè)視圖的位置和大小。 if (splitView.frame.size.width == oldSize.width) { splitView.adjustSubviews() return } //以下的代碼只是用來(lái)說(shuō)明需要自己計(jì)算位置和大小昆婿,并沒(méi)有任何實(shí)質(zhì)意義球碉,可以不必仔細(xì)閱讀 for var index = 0; index < splitView.subviews.count; index++ { let subview = splitView.subviews[index] as! NSView subview.frame = NSMakeRect((splitView.frame.size.width - dividerThickness) / CGFloat(splitView.subviews.count) * CGFloat(index) + CGFloat(index) * dividerThickness, 0, (splitView.frame.size.width - dividerThickness) / CGFloat(splitView.subviews.count), splitView.frame.size.height) } }

另,NSSplitViewController是OS X 10.10中新加入的api挖诸,用起來(lái)是非常方便的汁尺,但是如果需要考慮向下兼容的話還是不要用了。

以上是筆者遇到的一些問(wèn)題多律,如果有地方表達(dá)不是很清楚的話歡迎與我交流痴突。QQ:2680914103 轉(zhuǎn)載請(qǐng)注明出處,感謝支持

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末狼荞,一起剝皮案震驚了整個(gè)濱河市辽装,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌相味,老刑警劉巖拾积,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異丰涉,居然都是意外死亡拓巧,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)一死,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)肛度,“玉大人,你說(shuō)我怎么就攤上這事投慈〕泄ⅲ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵伪煤,是天一觀的道長(zhǎng)加袋。 經(jīng)常有香客問(wèn)我,道長(zhǎng)抱既,這世上最難降的妖魔是什么职烧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮蝙砌,結(jié)果婚禮上阳堕,老公的妹妹穿的比我還像新娘。我一直安慰自己择克,他們只是感情好恬总,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著肚邢,像睡著了一般壹堰。 火紅的嫁衣襯著肌膚如雪拭卿。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天贱纠,我揣著相機(jī)與錄音峻厚,去河邊找鬼。 笑死谆焊,一個(gè)胖子當(dāng)著我的面吹牛惠桃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辖试,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辜王,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了罐孝?” 一聲冷哼從身側(cè)響起呐馆,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蒲稳,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年丁寄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖闺阱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舵变,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布瘦穆,位于F島的核電站纪隙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏扛或。R本人自食惡果不足惜绵咱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望熙兔。 院中可真熱鬧悲伶,春花似錦、人聲如沸住涉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舆声。三九已至花沉,卻和暖如春柳爽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背碱屁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工磷脯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人娩脾。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓赵誓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親柿赊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子俩功,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容