日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《iOS创意程序设计家》——第6.2节导航栏控制器UINavigationController

發布時間:2024/4/14 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《iOS创意程序设计家》——第6.2节导航栏控制器UINavigationController 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本節書摘來自異步社區《iOS創意程序設計家》一書中的第6章,第6.2節導航欄控制器UINavigationController,作者 林柏全,更多章節內容可以訪問云棲社區“異步社區”公眾號查看

6.2 導航欄控制器UINavigationController
iOS創意程序設計家
導航欄控制器(UINavigationController)位于界面的最上方,主要用于將具有因果關系的界面連接起來,它由幾個元素組成:左邊按鈕、右邊按鈕以及標題。我們可以通過導航欄的navigationItem來訪問這3個元素。其中,左右兩邊的按鈕都是UIBarButtonItem類,我們可以通過navigationItem.rightBarButtonItem以及navigationItem.leftBarButtonItem來設置這兩個按鈕。如果希望界面上不出現任何一邊的按鈕,那么只要將其設置為nil就可以了。至于中間標題的部分,我們也可以通過titleView來訪問。例如:

self.navigationController.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"title"]];

由于titleView本身就是一個UIView,因此,也可以通過addSubview:的方式將其他界面控件加入到標題欄中。

從故事板中,我們可以很清楚地看出導航欄應用程序中界面的組成方式。這些界面形成了界面堆棧,由導航欄負責維護這些界面間的前后關系,如圖6.5所示。



6.2.1 界面堆棧的概念
界面堆棧主要負責維護界面間的前后關系,不過,這里所謂的界面是以UIViewController為單位的,而不是UIView。它有點像是界面的歷史記錄,可以讓您回到上一個界面。在UINavigation-Controller這個類中,有一個viewControllers屬性,您可以很輕易地通過這個屬性來訪問界面堆棧,或是通過topViewController來取得位于該堆棧內最上層的界面。

那么,我們怎么將界面推入這個堆棧里面呢?除了通過viewControllers這個屬性外,也可以通過pushViewController:animated:來將另一個UIViewController推入到堆棧中。被推入堆棧后的UIViewController所控制的界面就會位于該堆棧內最上層的界面,從而形成了界面切換的效果。pushViewController:在使用的時候有一個限制,其后面的參數只能是UIViewController,而不能是UINavigationController。如果您執意要將UINavigationController推入堆棧,那么應該使用presentViewController: animated: completion:來取代上面的方法。

好了,現在來看看在這個堆棧的過程中發生了哪些事情。當一個UIViewController被置入堆棧里面的時候,它會變為該堆棧里面最上層的界面控制器,當然,導航欄的界面也會隨之更新,界面也會自動調整為適當的大小。這個時候,您可以發現導航欄的左邊出現了一個按鈕,而這個按鈕上的文字正是上一個界面的標題。

這個標題的文字其實是在每一個UIViewController設置好的,您可以通過title屬性來設置每一個界面的標題。如果忘了設置這些界面的標題,您將看不到返回鍵,但是,在相對應的位置按下時,這些返回鍵仍會有作用。除了使用上一頁的標題作為返回鍵的文字外,也可以通過navigationItem.back
BarButtonItem來指定一個自定義的按鈕或標題。不論是通過title還是navigationItem.backBar
ButtonItem來設置返回鍵,您都應該在上一頁的UIViewController中設置,而不是在當前的頁面內設置。

現在試著查詢UIViewController的API,您會發現一件很有趣的事情,原來的UIViewController中就有一個navigationController的屬性(而UINavigationContoller中有viewControllers屬性)。如果在新建項目的時候不是使用Master-Detail應用程序樣板的話,那么這個屬性將會是nil,這是因為Master-Detail的應用程序已經幫您做好了關聯。關于這一點,大家可以通過編輯器的版本模式來觀察。

現在我們來看看相反的操作,也就是讓界面回到上一頁。可以通過UINavigationController的popViewControllerAnimated:方法來回到上一個界面,或是通過popToRootViewController- Animated:方法來將堆棧中除了最開始的界面外的界面全部退出堆棧。

好了,了解界面堆棧的使用后,我們來看一個實際的例子。您可以先把其他的界面準備好,然后通過UIViewController類的initWithNibName加載進來。例如,可以在XCode產生的ViewController類里面用下面這樣的方式來切換界面。

AnotherViewController *anotherViewController= [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil]; [self.navigationController pushViewController:anotherViewController animated:YES]; 我們剛剛提到pushViewController:后面的參數不可以是一個UINavigationController的對象,如果真碰上這種情況,就應該使用以下代碼:[self.navigationController presentViewController:anotherViewController animated:YES completion:nil]; 最后,別忘了設置目前界面的標題,否則界面上就不會出現返回鍵。self.title = @"First page";

6.2.2 使用故事板來處理界面堆棧
如果完全采用故事板的方式來設計界面,那么不需要使用諸如pushViewController:animated:的方式來處理界面堆棧。可以直接在兩個界面間設置好它們的連接(Segue),然后一切的工作就交由系統自己去處理了。不過有些時候,兩個界面間的連接也有可能會有多種情況發生,這通常是因為用戶在第1個界面做了某些操作而導致第2個界面出現的結果不同。這時候,我們可以設置多個連接(Segue),然后再由程序去判斷要走哪一條路徑。

比如,在下面的界面中,我們可以將輸入密碼的界面與登錄成功和登錄失敗的界面分別連接起來。選中連接后,在屬性觀測窗口中為每個連接設置一個標識符,在程序里面就可以通過這個標識符來判斷要走的路徑,如圖6.6所示。例如,可以在第一個界面的View Controller中寫入如下程序代碼。

if( 登錄成功 )[self performSegueWithIdentifier:@"LoginSuccessSegue" sender:nil]; else[self performSegueWithIdentifier:@"LogiFailSegue" sender:nil];

這樣一來,界面就會跟著程序內的邏輯來跑了。



注意:
① 如果嘗試將按鈕鏈接到下一個界面,會發現路徑只能有一個。如果希望做到上述的效果,那么應該將兩個View Controller連接起來才對。

② 除了上述的方式外,也可以在AppDelegate.m中去編寫這樣的程序代碼,以決定第一個界面是什么。其中,“LoginViewController”與“ViewController”是我們為不同的View Controller在屬性觀測窗口(attribute inspector)所設置的標識符。

UIStoryboard *storyboard = self.window.rootViewController.storyboard; if( 未記憶密碼 )self.window.rootViewController = [storyboardinstantiateViewControllerWithIdentifier:@"LoginViewController"]; elseself.window.rootViewController = [storyboardinstantiateViewControllerWithIdentifier:@"ViewController"];

6.2.3 單選按鈕
iPhone內建的通訊錄其實就是一個很典型的導航欄模式,讀者們應該也注意到了吧。我們可以看到在導航欄的右邊有一個加號的按鈕,這是怎么加上去的呢?其實導航欄控制器已經預留了左右兩邊的按鈕。您可以在導航欄的兩邊各放入一個UIBarButtonItem類的按鈕,使用的代碼如下:

UIBarButtonItem * item=[[UIBarButtonItem alloc] initWithTitle:@"Done" style: UIBarButtonItemStyleDone target:self action:@selector(clickButtonItem)]; self.navigationController.navigationItem.rightBarButtonItem = item; self.navigationController.navigationItem.leftBarButtonItem = nil;

把rightBarButtonItem 或leftBarButtonItem設置為nil時,導航欄原有的按鈕就不見了,這個技巧可以應用到諸如文本編輯器這樣的應用程序上。我們在第5章的UITextViewDemo的例子里面就已經運用了這個技巧。

可以使用的按鈕的類型包括以下幾種:

typedef enum {UIBarButtonItemStylePlain,UIBarButtonItemStyleBordered,UIBarButtonItemStyleDone, } UIBarButtonItemStyle;

如果不想使用自定義的按鈕樣式,也可以直接使用系統內定的按鈕類型,不過在初始化的時候得改用initWithBarButtonSystemItem:的構造函數,使用代碼如下:

UIBarButtonItem * item=[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemDonetarget:self action:@selector(clickButtonItem)]; 系統默認的按鈕則有以下幾種:typedef enum {UIBarButtonSystemItemDone,UIBarButtonSystemItemCancel,UIBarButtonSystemItemEdit, UIBarButtonSystemItemSave, UIBarButtonSystemItemAdd,UIBarButtonSystemItemFlexibleSpace,UIBarButtonSystemItemFixedSpace,UIBarButtonSystemItemCompose,UIBarButtonSystemItemReply,UIBarButtonSystemItemAction,UIBarButtonSystemItemOrganize,UIBarButtonSystemItemBookmarks,UIBarButtonSystemItemSearch,UIBarButtonSystemItemRefresh,UIBarButtonSystemItemStop,UIBarButtonSystemItemCamera,UIBarButtonSystemItemTrash,UIBarButtonSystemItemPlay,UIBarButtonSystemItemPause,UIBarButtonSystemItemRewind,UIBarButtonSystemItemFastForward, } UIBarButtonSystemItem;

值得一提的是,一旦決定使用系統按鈕,您將無法改變上面的標題文字;反之,可以通過UIBarButtonItem的title屬性來動態地改變上面的文字。除了文字的按鈕外,也可以通過圖片的方式來呈現,使用代碼如下:

UIBarButtonItem * item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"done"] style:UIBarButtonItemStylePlain target:self action:@selector(clickButtonItem)];

6.2.4 如何建立導航欄應用程序
在所有的項目樣板中只有Master-Detail的應用程序才會默認產生導航欄,在其他的樣板中,我們都得自己去建立一個導航欄控制器。下面的內容將介紹如何在設計界面中建立導航欄控制器。可以使用XIB或是故事板來建立這個應用程序,如果可能的話,盡量使用故事板的方式,在開發上會更為直觀些。

請記得勾選“Use Storyboard”以及“Use Automatic Reference Counting”選項。

如同往常一樣,您應該可以看到一個空白的手機界面。現在,選中這個View Controller,并按下刪除鍵將這個界面刪除。現在的界面上應該是空無一物了。

導航欄控制器默認會帶有一個UIViewController,而這個UIViewController就是它的界面堆棧內的第一個界面。現在,可以試著在這個UIViewController的標題欄的地方雙擊后輸入它的標題文字。現在的界面看起來應該如圖6.7所示。



完成之后,可以試著執行應用程序,您會發現界面上竟然是一片黑色的界面,這是因為我們還沒有指定故事從哪邊開始的緣故。

每個故事板的一開始一定要有一個起始的界面控制器。所以請選中界面中的Navigation Controller控制器,切換到屬性觀測窗口,并勾選“Is initial View Controller”,如圖6.8所示。現在再試著執行看看,您應該可以看到第一個界面了。



接下來,我們要產生第2個界面。還記得導航欄控制器是將整個UIViewController推入到界面的堆棧里面吧。所以,在這里,我們必須要由控件庫中拉入一個非導航欄的控制器。例如一個UIViewController,如圖6.10所示。



現在再執行一下您的應用程序,應該可以順利地由第1個界面切換到第2個界面了。

總結

以上是生活随笔為你收集整理的《iOS创意程序设计家》——第6.2节导航栏控制器UINavigationController的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。