原文 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. 开启level1s​​creen.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. 在level1s​​creen.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. 开启level1s​​creen.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(truetrue);</span> this.NavigationController.SetNavigationBarHidden(truetrue);</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(falsetrue);</span> this.NavigationController.SetNavigationBarHidden(falsetrue);</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多页面应用程式开发的更多相关文章

  1. Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发

    原文 Visual Studio跨平台开发实战(5) - Xamarin Android多页面应用程式开发 前言 大部份的Andr​​oid 都具有实体或虚拟的Back键. 因此在处理多页面应用程式时 ...

  2. Visual Studio跨平台开发实战(2) - Xamarin.iOS基本控制项介绍

    原文 Visual Studio跨平台开发实战(2) - Xamarin.iOS基本控制项介绍 前言 在上一篇文章中, 我们介绍了Xamarin 以及简单的HelloWorld范例, 这次我们针对iO ...

  3. Visual Studio跨平台开发(3):Xamarin iOS多页面应用开发

    前言 在前一篇教学中, 我们学会如何使用Visual Studio 搭配Xcode进行iOS基本控制项的操作. 但都是属于单一画面的应用程式. 这次我们要来练习如何通过Navigation Contr ...

  4. Visual Studio跨平台开发实战(4) - Xamarin Android基本控制项介绍

    原文 Visual Studio跨平台开发实战(4) - Xamarin Android基本控制项介绍 前言 不同于iOS,Xamarin 在Visual Studio中针对Android,可以直接设 ...

  5. Visual Studio跨平台开发(2):Xamarin.iOS基本控制项介绍

    前言 在上一篇文章中, 我们介绍了Xamarin 以及简单的HelloWorld范例, 这次我们针对iOS的专案目录架构以及基本控制项进行说明. 包含UIButton,UISlider,UISwitc ...

  6. Visual Studio跨平台开发(5):Xamarin Android多页面应用开发

    前言 大部份的Android 都具有实体或虚拟的Back键. 因此在处理多页面应用程序时, 与先前所介绍的iOS Navigation controller 比较起来会简单许多. 1. 开启Visua ...

  7. Visual Studio跨平台开发实战(1) - Hello Xamarin!

    原文 Visual Studio跨平台开发实战(1) - Hello Xamarin! 前言 应用程式发展的脚步, 从来没有停过. 从早期的Windows 应用程式, 到网路时代的web 应用程式, ...

  8. Visual Studio跨平台开发(4):Xamarin Android控制项介绍

    前言 不同于iOS, Xamarin 在Visual Studio中针对Android, 可以直接设计使用者界面. 在本篇教学文章中, 笔者会针对Android的专案目录结构以及基本控制项进行介绍, ...

  9. Visual Studio跨平台开发(1):Hello Xamarin!

    前言 应用程序发展的脚步, 从来没有停过. 从早期的Windows 应用程序, 到网络时代的web 应用程序, 再到近几年相当盛行的行动装置应用程序(Mobile Application), 身为C# ...

随机推荐

  1. 通过OpenSSL解码X509证书文件

    在Windows平台下.假设要解析一个X509证书文件,最直接的办法是使用微软的CryptoAPI. 可是在非Windows平台下,就仅仅能使用强大的开源跨平台库OpenSSL了.一个X509证书通过 ...

  2. HDU 5045(Contest-费用流)[template:费用流]

    Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submi ...

  3. java如何运行OS命令(转)

    •javac TestRunTime.java•java TestRunTime hostname // 执行“hostname”Linux命令•即可看到输出 import java.io.IOExc ...

  4. ExtJs4 笔记(5) Ext.Button 按钮

    id="li2"></li> <li id="li3"></li> </ul> </div> ...

  5. 使用iftop网络流量监控

    iftop这是一个非常有用的工具.下面的命令监视无线网卡在我的笔记本 iftop -i wlan0 比如,我现在玩音乐视频.iftop显示的信息: 基本说明: 1. 屏幕主要部分都是表示两个机器之间的 ...

  6. xcode5下一个ffmpeg静态库配置

    1.若要安装xcode命令行工具 1).xcode5安装命令行工具方法: 在终端运行命令Using xcode-select --install 2).xcode5之前安装命令行工具方法: 2.xco ...

  7. Contact类解析

    Contact类 public static class Contacts implements BaseColumns, ContactsColumns, ContactOptionsColumns ...

  8. uva 10655 - Contemplation! Algebra(矩阵高速幂)

    题目连接:uva 10655 - Contemplation! Algebra 题目大意:输入非负整数,p.q,n,求an+bn的值,当中a和b满足a+b=p,ab=q,注意a和b不一定是实数. 解题 ...

  9. sql server 2012 数据库还原方法

    USE master RESTORE DATABASE WSS_Content FROM DISK = N'D:\bak\contentbak.bak' WITH REPLACE, NORECOVER ...

  10. 多项式相乘(C语言)

    //两个多项式的系数f分别存在x[]和y[]中,下标即为次数,*Max表示本多项式最高次数 int MX_double( double x[], int xMax, double y[], int y ...