uimenucontroller的使用
uimenucontroller的展現需要基于一個view視圖,其交互則需要基于其所在view視圖的responder。舉例來說,如果一個uimenucontroller展現在當前viewcontroller的view上,則此uimenucontroller的交互邏輯交由當前的viewcontroller進行管理。
在界面展示出uimenucontroller需要3個條件:
1.當前的responder處于第一響應。
2.uimenucontroller對象調用menuvisible方法。
3.當前的responder實現了如下兩個方法:
1
2
3
4
5
6
7
8
|
//是否可以成為第一相應 -( bool )canbecomefirstresponder{ return yes; } //是否可以接收某些菜單的某些交互操作 -( bool )canperformaction:(sel)action withsender:(id)sender{ return yes; } |
實現了上面的兩個方法,使用如下的代碼可以喚出uimenucontroller控件:
1
2
3
4
5
|
[self becomefirstresponder]; //設置菜單顯示的位置 frame設置其文職 inview設置其所在的視圖 [[uimenucontroller sharedmenucontroller] settargetrect:frame inview:self.view]; //將菜單控件設置為可見 [uimenucontroller sharedmenucontroller].menuvisible = yes; |
在執行了上面的代碼后,系統第一次調用canperformaction:withsender:方法會進行是否顯示菜單欄的檢測,如果返回為no,則不能顯示菜單欄,如果返回為yes,之后系統會多次調用canperformaction:withsender:方法,用于檢測當前responder對象是否實現了菜單欄上某個選項的觸發方法,如果實現了,菜單欄上面的相應按鈕會顯示,否則不會顯示。開發者可以在這個方法中通過判斷action來確定菜單控件中顯示的按鈕種類。系統默認為開發者提供了一系列的菜單按鈕,例如要顯示剪切和賦值操作的菜單按鈕,示例代碼如下:
1
2
3
4
5
6
|
-( bool )canperformaction:(sel)action withsender:(id)sender{ if (action == @selector(cut:)||action == @selector(copy:)) { return yes; } return no; } |
效果如下圖所示:
系統默認支持提供的按鈕觸發方法列舉如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//剪切按鈕的方法 - ( void )cut:(nullable id)sender ns_available_ios(3_0); //復制按鈕的方法 - ( void )copy:(nullable id)sender ns_available_ios(3_0); //粘貼按鈕的方法 - ( void )paste:(nullable id)sender ns_available_ios(3_0); //選擇按鈕的方法 - ( void )select:(nullable id)sender ns_available_ios(3_0); //全選按鈕的方法 - ( void )selectall:(nullable id)sender ns_available_ios(3_0); //刪除按鈕的方法 - ( void ) delete :(nullable id)sender ns_available_ios(3_2); //改變書寫模式為從左向右按鈕觸發的方法 - ( void )maketextwritingdirectionlefttoright:(nullable id)sender ns_available_ios(5_0); //改變書寫模式為從右向左按鈕觸發的方法 - ( void )maketextwritingdirectionrighttoleft:(nullable id)sender ns_available_ios(5_0); |
上面所列舉的方法聲明在uiresponder頭文件中,實際上,除了上面的方法,關于uimenucontroller上面的按鈕,系統中還有許多私有方法,列舉如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
//替換按鈕 - ( void )_promptforreplace:(id)arg1{ nslog(@ "promptforreplace" ); } //簡體繁體轉換按鈕 -( void )_transliteratechinese:(id)sender{ nslog(@ "transliteratechinese" ); } //文字風格按鈕 -( void )_showtextstyleoptions:(id)sender{ nslog(@ "showtextstyleoptions" ); } //定義按鈕 -( void )_define:(id)sender{ nslog(@ "define" ); } -( void )_addshortcut:(id)sender{ nslog(@ "addshortcut" ); } -( void )_accessibilityspeak:(id)sender{ nslog(@ "accessibilityspeak" ); } //語言選擇按鈕 -( void )_accessibilityspeaklanguageselection:(id)sender{ nslog(@ "accessibilityspeaklanguageselection" ); } //暫停發音按鈕 -( void )_accessibilitypausespeaking:(id)sender{ nslog(@ "accessibilitypausespeaking" ); } //分享按鈕 -( void )_share:(id)sender{ nslog(@ "share" ); } |
實例進階
在實際開發中,開發這完全不需要使用這些私有的方法,uimenuitem類提供給開發者進行自定義菜單按鈕與觸發方法,示例如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[self becomefirstresponder]; uimenuitem * item = [[uimenuitem alloc]initwithtitle:@ "自定義" action:@selector(newfunc)]; [[uimenucontroller sharedmenucontroller] settargetrect:[sender frame] inview:self.view]; [uimenucontroller sharedmenucontroller].menuitems = @[item]; [uimenucontroller sharedmenucontroller].menuvisible = yes; -( bool )canbecomefirstresponder{ return yes; } -( bool )canperformaction:(sel)action withsender:(id)sender{ if (action == @selector(newfunc)) { return yes; } return no; } -( void )newfunc{ nslog(@ "自定義方法" ); } |
效果如下圖所示:
uimenucontroller還有如下的屬性用來設置其顯示的位置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//顯示的位置 @property(nonatomic) uimenucontrollerarrowdirection arrowdirection; //枚舉如下: /* typedef ns_enum(nsinteger, uimenucontrollerarrowdirection) { //默認 基于當前屏幕狀態 uimenucontrollerarrowdefault, // up or down based on screen location //箭頭在上的顯示模式 uimenucontrollerarrowup ns_enum_available_ios(3_2), //箭頭在下的顯示模式 uimenucontrollerarrowdown ns_enum_available_ios(3_2), //箭頭在左的顯示模式 uimenucontrollerarrowleft ns_enum_available_ios(3_2), //箭頭在右的顯示模式 uimenucontrollerarrowright ns_enum_available_ios(3_2), }; */ |
注意點總結
要正常顯示菜單,必須做到以下幾點:
1. -(bool)canbecomefirstresponder 必須返回yes
2. -(bool)canperformaction:(sel)action withsender:(id)sender
該函數中,要顯示的菜單項(包括系統的菜單項)的方法必須返回yes
3. 在顯示菜單前,必須調用:
1
|
[self becomefirstresponder] |
成為第一個響應者
4. 為了馬上可以正常顯示第二個菜單,必須使用:
1
|
[menucontroller setmenuvisible:no]; |
先關閉一下,不然就顯示不出來!