Visual Studio跨平台开发实战(3) - Xamarin iOS多页面应用程式开发
原文 Visual Studio跨平台开发实战(3) - Xamarin iOS多页面应用程式开发
前言
在前一篇教学中, 我们学会如何使用Visual Studio 搭配Xcode 进行iOS基本控制项的操作. 但都是属于单一画面的应用程式. 这次我们要来练习如何透过Navigation Controller来建立多页面的iOS应用程式.
![]()
设定专案及画面
1. 开启Xamarin Studio 并建立新专案, 专案类型为iOS=>iPhone=>空白专案, 专案名称为02-Navigation.
2. 在专案中添加3个iPhone View Controller 的档案, 档案名称如下:
- HomeScreen
Level1Screen
Level2Screen
新增后档案结构如下图所示:

3. 双击HomeScreen.xib 以开启Xcode.
4. 点选编辑区的HomeScreen, 并在右边的Attributes Inpsctor将Top Bar变更为”Navigation Bar”

5. 在Object Library中拖拉一个Button至画面中并将文字改为”Go to Level 1 Screen”

6. 为Button建立一个Outlet并命名为”btnToLv1”. 之后请关闭Xcode

7. 在Visual Studio 中开启此专案, 在专案属性中设定应用程式名称及版本等资讯, 并开启” AppDelegate.cs” 档. 在FinishedLaunching事件中加入以下程式码:
01 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//初始化UINavigationController</span> //初始化UINavigationController</span> |
02 |
03 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">var rootNavigationController = new UINavigationController();</span> var rootNavigationController = new UINavigationController();</span> |
04 |
05 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//初始化HomeScreen</span> //初始化HomeScreen</span> |
06 |
07 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">HomeScreen home = new HomeScreen();</span> HomeScreen home = new HomeScreen();</span> |
08 |
09 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//將HomeScreen加入到rootNavigationController</span> //将HomeScreen加入到rootNavigationController</span> |
10 |
11 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">rootNavigationController.PushViewController(home, false);</span> rootNavigationController.PushViewController(home, false);</span> |
12 |
13 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//將rootNavigationController 設為Window的RootViewController</span> //将rootNavigationController 设为Window的RootViewController</span> |
14 |
15 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">this.window.RootViewController = rootNavigationController;</span> this.window.RootViewController = rootNavigationController;</span> |
完成后的FinishedLaunching方法如下图所示:

在上面的程式码中, 我们先初始化Window, UINavigationController以及HomeScreen物件. 接着透过PushViewController方法将HomeScreen加入到NavigationController. 然后将rootNavigationController指定到Window.RootViewController属性. 最后则是显示Window.
8. 开启HomeScreen.cs, 在建构子中设定主画面的标题
1 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">public HomeScreen()</span> public HomeScreen()</span> |
2 |
3 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">: base("HomeScreen", null)</span> : base("HomeScreen", null)</span> |
4 |
5 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">{</span> {</span> |
6 |
7 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">this.Title = "我是主畫面";</span> this.Title = "我是主画面";</span> |
8 |
9 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> |
9. 执行专案后的结果如下:

载入Level 1 Screen
1. 我们要在点击主页面上的button后载入Level1Screen. 因此我们开启HomeScreen.cs. 在类别下先宣告Level1Screen物件.
1 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//宣告Level 1 screen</span> //宣告Level 1 screen</span> |
2 |
3 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Level1Screen lv1scr;</span> Level1Screen lv1scr;</span> |
在ViewDidLoad事件中, 加入btnToLv1的touchupinside事件处理, 程式码如下:
01 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//撰寫HomeScreen的BtnToLv1按鈕事件, 判斷先前是否已瀏覽過level 1 screen,</span> //撰写HomeScreen的BtnToLv1按钮事件, 判断先前是否已浏览过level 1 screen,</span> |
02 |
03 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//若無, 則進行初始化並將lv1scr加入NavigationController</span> //若无, 则进行初始化并将lv1scr加入NavigationController</span> |
04 |
05 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">this.btnToLv1.TouchUpInside += (sender, e) =>{</span> this.btnToLv1.TouchUpInside += (sender, e) =>{</span> |
06 |
07 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">if (this.lv1scr == null) { this.lv1scr = new Level1Screen(); }</span> if (this.lv1scr == null) { this.lv1scr = new Level1Screen(); }</span> |
08 |
09 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">this.NavigationController.PushViewController(lv1scr, true);</span> this.NavigationController.PushViewController(lv1scr, true);</span> |
10 |
11 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">};</span> };</span> |
在上述程式码中, 我们同样透过PushViewController方法将Level1Screen加入到Navigation控制项.
2. 执行专案并在主画面中点击按钮以载入Level 1 Screen. 您会看到空白画面被载入, 且NavigationBar左边的按钮会显示上一个页面的Title

新增NavigationBar右边的按钮载入Level 2 Screen
在前一个练习, 我们载入了Level 1 Screen, NavigationBar左边是回到上一个页面, 在这个练习中, 我们要在NavigationBar中新增右边的按钮, 并透过按钮来载入Level 2 Screen.
1. 开启level1screen.cs, 并在类别下加入Level2Screen的宣告
1 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//宣告Level 2 screen</span> //宣告Level 2 screen</span> |
2 |
3 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">Level2Screen lv2scr;</span> Level2Screen lv2scr;</span> |
2. 在level1screen.cs的ViewDidLoad事件中, 加入以下程式码:
1 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//設定右邊按鈕this.NavigationItem.SetRightBarButtonItem(new UIBarButtonItem(UIBarButtonSystemItem.Edit, (sender, e) =></span> //设定右边按钮this.NavigationItem.SetRightBarButtonItem(new UIBarButtonItem(UIBarButtonSystemItem.Edit, (sender, e) =></span> |
2 |
3 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">{</span> {</span> |
4 |
5 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">if (this.lv2scr == null) { this.lv2scr = new Level2Screen(); }</span> if (this.lv2scr == null) { this.lv2scr = new Level2Screen(); }</span> |
6 |
7 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">this.NavigationController.PushViewController(lv2scr, true);</span> this.NavigationController.PushViewController(lv2scr, true);</span> |
8 |
9 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}), true);</span> }), true);</span> |
我们透过SetRightBarButtonItem方法, 新增一个UIBarButtonItem, 在这里我们使用系统内建的Edit项目. 您也可以使用自订的图示或文字来建立. 并在第2个参数, 直接透过Lambda Expression 来建立按钮按下去的处理. 我们同样透过PushViewController方法将Level 2 Screen载入.
3. 执行专案的结果如下:

按下Level 1 右边的”Edit”按钮, 便会载入Level 2 Screen. 因为我们没有设定Level 1 Screen的Title, 因此在Level 2 Screen左边的按钮会显示预设的”Back”

客制NavigationBar左边的按钮
在目前的练习中, NavigationBar左边按钮的显示文字为上一个画面的Title, 若没有设定Title则会显示Back. 接下来我们来客制Level 1 Screen左边的按钮文字, 方法如下:
1. 开启level1screen.cs, 在ViewDidLoad事件中, 新增以下程式码:
1 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//客製化左邊按扭this.NavigationItem.SetLeftBarButtonItem(new UIBarButtonItem("回到主畫面", UIBarButtonItemStyle.Plain,</span> //客制化左边按扭this.NavigationItem.SetLeftBarButtonItem(new UIBarButtonItem("回到主画面", UIBarButtonItemStyle.Plain,</span> |
2 |
3 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">(sender, e) =></span> (sender, e) =></span> |
4 |
5 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">{</span> {</span> |
6 |
7 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">this.NavigationController.PopViewControllerAnimated(true);</span> this.NavigationController.PopViewControllerAnimated(true);</span> |
8 |
9 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}), true);</span> }), true);</span> |
由上述的程式码可知, 我们同样是呼叫SetLeftBarButtonItem (刚刚是SetRightBarButtonItem)的方式, 新增一个按钮来取代预设的按钮. 然后输入自订的文字”回到主画面”.
2. 执行专案的结果如下:

可以对照一下先前的执行结果, NavigationBar左边按钮的文字已经取代为我们自订的文字了.
隐藏主画面的NavigationBar
如果不想在主画面中也显示NavigationBar, 可以透过在HomeScreen.cs中新增ViewWillAppear及ViewWillDisappear事件处理来将主画面中的NavigationBar隐藏起来, 程式码如下:
01 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">//透過ViewWillAppear及ViewWillDisappear 事件將Home Screen的Navigation controller 隱藏public override void ViewWillAppear(bool animated) {</span> //透过ViewWillAppear及ViewWillDisappear 事件将Home Screen的Navigation controller 隐藏public override void ViewWillAppear(bool animated) {</span> |
02 |
03 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">base.ViewWillAppear(animated);</span> base.ViewWillAppear(animated);</span> |
04 |
05 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">this.NavigationController.SetNavigationBarHidden(true, true);</span> this.NavigationController.SetNavigationBarHidden(true, true);</span> |
06 |
07 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> |
08 |
09 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">public override void ViewWillDisappear(bool animated) {</span> public override void ViewWillDisappear(bool animated) {</span> |
10 |
11 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">base.ViewWillDisappear(animated);</span> base.ViewWillDisappear(animated);</span> |
12 |
13 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">this.NavigationController.SetNavigationBarHidden(false, true);</span> this.NavigationController.SetNavigationBarHidden(false, true);</span> |
14 |
15 |
<span class="notranslate" onmouseover="_tipon(this)" onmouseout="_tipoff()"><span class="google-src-text" style="direction: ltr; text-align: left">}</span> }</span> |
执行结果如下:

结语
本篇文章说明如何透过Navigation controller来建立多页面的iOS 应用程式. 在iOS中还有其他建立多页面应用程式的方法, 例如Tab控制项可以透过画面下方的页签来切换不同画面. Storyboard 可以透过Interface Builder来建立应用程式的多个画面以及画面之间的连结. 有兴趣的朋友可以参考以下文章:
Using XCode, Interface Builder, and Storyboards
http://docs.xamarin.com/guides/ios/user_interface/tables/part_5_-_using_xcode,_interface_builder,_and_storyboards
Creating Tabbed Applications
http://docs.xamarin.com/guides/ios/user_interface/creating_tabbed_applications
范例程式码下载: Lab02-Navigation.zip
本文同时刊载于昕力资讯网站 ,转载请注明出处!
Visual Studio跨平台开发实战(3) - Xamarin iOS多页面应用程式开发的更多相关文章
- Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发
原文 Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发 前言 大部份的Android 都具有实体或虚拟的Back键. 因此在处理多页面应用程式时 ...
- Visual Studio跨平台开发实战(2) - Xamarin.iOS基本控制项介绍
原文 Visual Studio跨平台开发实战(2) - Xamarin.iOS基本控制项介绍 前言 在上一篇文章中, 我们介绍了Xamarin 以及简单的HelloWorld范例, 这次我们针对iO ...
- Visual Studio跨平台开发(3):Xamarin iOS多页面应用开发
前言 在前一篇教学中, 我们学会如何使用Visual Studio 搭配Xcode进行iOS基本控制项的操作. 但都是属于单一画面的应用程式. 这次我们要来练习如何通过Navigation Contr ...
- Visual Studio跨平台开发实战(4) - Xamarin Android基本控制项介绍
原文 Visual Studio跨平台开发实战(4) - Xamarin Android基本控制项介绍 前言 不同于iOS,Xamarin 在Visual Studio中针对Android,可以直接设 ...
- Visual Studio跨平台开发(2):Xamarin.iOS基本控制项介绍
前言 在上一篇文章中, 我们介绍了Xamarin 以及简单的HelloWorld范例, 这次我们针对iOS的专案目录架构以及基本控制项进行说明. 包含UIButton,UISlider,UISwitc ...
- Visual Studio跨平台开发(5):Xamarin Android多页面应用开发
前言 大部份的Android 都具有实体或虚拟的Back键. 因此在处理多页面应用程序时, 与先前所介绍的iOS Navigation controller 比较起来会简单许多. 1. 开启Visua ...
- Visual Studio跨平台开发实战(1) - Hello Xamarin!
原文 Visual Studio跨平台开发实战(1) - Hello Xamarin! 前言 应用程式发展的脚步, 从来没有停过. 从早期的Windows 应用程式, 到网路时代的web 应用程式, ...
- Visual Studio跨平台开发(4):Xamarin Android控制项介绍
前言 不同于iOS, Xamarin 在Visual Studio中针对Android, 可以直接设计使用者界面. 在本篇教学文章中, 笔者会针对Android的专案目录结构以及基本控制项进行介绍, ...
- Visual Studio跨平台开发(1):Hello Xamarin!
前言 应用程序发展的脚步, 从来没有停过. 从早期的Windows 应用程序, 到网络时代的web 应用程序, 再到近几年相当盛行的行动装置应用程序(Mobile Application), 身为C# ...
随机推荐
- 基础知识(3)- Java的基本程序设计结构
3.1 一个简单的Java应用程序 3.2 注释 3.3 数据类型 3.3.1 整型 3.3.2 浮点类型 3.3.3 char类型 3.3.4 boolean类型 3.4 变量 3.4.1 ...
- 图解UML类与类之间的六中关系
大话设计模式上的一个图,我用EA画出来的: UML中的6大关系相关英文及音标: 依赖关系 dependency [di'pendənsi] 关联关系 association [ə,səuʃi' ...
- Java常用代码段 - 未完待续
记录一些自己写项目常用的代码段. 格式化常用日期格式 Date date = new Date(System.currentTimeMillis()); DateFormat d3 = DateFor ...
- IDFA的值什么时候会发生改变
在何种情况下 , 应用的IDFA值会发生改变? 近期工作中须要获得一个能够唯一地标示每个不同应用的ID,之前的苹果UDID已经不让使用了. 那么我们须要使用新的IDFA来引用.可是在某些情况下这个ID ...
- Delphi事件的广播2
上篇文章写了将事件分离成类的方法来实现事件的广播,这次将参考观察者模式来实现事件的广播.模式中主要有这两个角色: 发布者:发布者保存着一张观察者的列表,以便在必要的时候调用观察者的方法. 观察者:观察 ...
- c#2解决c#1中的问题之用泛型实现参数化类型
为什么需要泛型 你手中还有c#1的代码吗?数一数其中的强制转换有多少,特别是那些大量使用集合的代码.几乎每次使用foreach都需要隐式的强制转换.使用那些为不同数据类型而设计的类型,就意味着强制转换 ...
- WinDBG 技巧:如何生成Dump 文件(.dump 命令)
程序崩溃(crash)的时候, 为了以后能够调试分析问题, 可以使用WinDBG要把当时程序内存空间数据都保存下来,生成的文件称为dump 文件. 步骤: 1) 打开WinDBG并将之Attach 到 ...
- CentOS6.5与window远程桌面配置
VNC配置手冊 一.服务端 VNC(Virtual Network Computing)是一种Linux系统(或者BSD.Mac等)下经常使用的图形化远程管理工具.使用的是RFB协议.VNC跟SSH一 ...
- 鸟哥之安裝 CentOS7.x
http://linux.vbird.org/linux_basic/0157installcentos7.php since 2002/01/01 新手建議 開始閱讀之前 網站導覽 Linux 基礎 ...
- SilkTest高级进阶系列8 – 放下榔头,立地成佛
在地球尚未毁灭的某天,手动测试的同事找到你所在的自动组,问是否可以帮助他们自动化一个需要连续添加100个条目的测试用例,因为他们觉得这是一个噩梦.你口头上说要先烟酒烟酒才能知道,但是内里早就满心欢喜: ...