《MonoTouch开发实践指南》一3.4 使用多个视图和控制器

简介: 本节书摘来自华章出版社《MonoTouch开发实践指南》一 书中的第3章,第3.4节,作者:(美)Michael Bluestein,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.4 使用多个视图和控制器

到目前为止,只是给SampleViewController的ViewDidLoad方法添加了代码。这只是子类化UIViewController的几种方法之一。采用哪种方法取决于需要交互的视图控制器的视图处于生命周期中的哪一个阶段。视图控制器不会在实例化的时候就创建它的视图,因为视图都是延时并按需加载的,也就是说,只有在屏幕上显示的时候才加载,这样做的目的是为了减少资源消耗。虽然视图控制器通常都会在应用程序的整个生命周期内一直存在,但它的视图可能在浏览应用程序时多次重新创建。对于单一视图的应用程序,这并没有太大影响,但当应用程序是多控制器和多视图时,就会变得相当复杂,通过延迟并按需加载视图,就会对应用程序的性能和最大限度地减少资源利用造成很大影响。要在控制器内处理视图的生命周期,需要使用之前讲述过的UIViewController的视图生命周期管理方法。
为了说明这一点,下面创建一个带有两个单独视图控制器及其相关视图的示例。第一个视图控制器就是之前创建的SampleViewController。目前要做的是,通过代码创建第二个视图控制器及其视图。此前曾提过UITabBarController,这里将使用这个控件管理视图并处理它们之间的切换。
创建一个名为LMT3-3的新工程。因为要重用SampleViewController作为UITabBarController的起始控制器,所以要复制SampleViewController.xib、SampleViewCont.xib.cs和SampleViewController.xib.designer.cs文件到MonoDevelop中的新工程内,并修改其命名空间为LMT33。一旦将这些文件拖放到解决方案树中,MonoDevelop就会知道如何保持文件的正确关联。
在新工程的AppDelegate中,创建UITabBarController并给它添加多个控制器。创建UITabBarController并添加视图到窗口的过程与其他控制器的过程是一样的。UITabBarController可以创建一个有标签的界面实现通过选择标签切换视图。控制器自身管理所包含的视图控制器之间的切换。
为了将控制器添加到UITabBarController,只要将UITabBarController的ViewControllers属性值设置为UIViewController的数组即可。在数组内,添加SampleViewController的实例为第一项,然后简单地创建一个空的UIViewController作为数组第二项的占位符。每一个称为“标签栏条目”(Tab Bar Item)的标签条目,可以通过每个添加到UITabBarController控制器的TabBarItem属性进行设置。使用TabBarItem,可以设置标签条目的标题和图标,不过现在不设置图标。最终的代码如代码清单3-4所示。
代码清单3-4 添加UIViewController到UITabBarController

public partial class AppDelegate : UIApplicationDelegate
{
    UITabBarController _tabController;
    SampleViewController _sampleVC;
    UIViewController _secondVC;

    public override bool FinishedLaunching (UIApplication app,
        NSDictionary options)
    {
        _tabController = new UITabBarController ();
        _sampleVC = new SampleViewController ();
        _sampleVC.TabBarItem.Title = "tab 1";

        _secondVC = new UIViewController ();
        _secondVC.TabBarItem.Title = "tab 2";

        _tabController.ViewControllers =
            new UIViewController[] { _sampleVC, _secondVC };

        window.AddSubview (_tabController.View);

        window.MakeKeyAndVisible ();

        return true;
    }
    ...
}

如果运行应用程序,第一个标签将会加载SampleViewController的视图,加速度计的数据将会像之前一样显示。如果切换到第二个标签,将会看到作为占位符添加的空白屏幕。切换回第一个标签,就会看到虽然切换到了第二个标签页,但加速度计的数据还在不断更新。当切换标签时,标签内的视图销毁与否,取决于它是否需要回收(例如,面对内存压力的时候),而当前示例不存在这个情况,所以视图还在继续更新数据。
提示 如果视图控制器接收到内存警告,并且它的视图没有在屏幕上显示,那么它就会卸载它的视图(当然,这也可通过重写默认配置实现)。当发生这种情况时,为了实现任何附加的清理代码,可在控制器子类的ViewDidUpload方法内实现。
如果要在视图没有显示时停止其活动,可以在控制器的ViewDidDisappear方法内处理。要停止接收加速度计的更新,最简单的方法是将委托设置为null。如果现在运行应用程序并在标签间来回切换,就会看到切换到第二个标签时,加速度计的数据并没有继续添加。然而,当切换回第一个标签时,数据也没有恢复添加。这是因为加速度计的实现代码是在ViewDidLoad方法内,而它只在视图第一次加载的时候才调用,而在视图显示或消失时,并不会调用它。为了实现每次视图显示时执行代码,可以在ViewDidAppear方法内实现。代码清单3-5列出了在SampleViewController的视图生命周期内实现更新的代码。如果现在运行应用程序,就可以看到当切换标签离开第一个视图时,加速度计就会停止记录更新,而切换回时就会恢复更新。
注意 也可以通过ViewWillAppear和ViewWillDisappear方法来实现之前在视图显示或消失时实现的效果。

代码清单3-5 SampleViewController中的视图生命周期方法

public partial class SampleViewController : UIViewController
{
    MyAccelerometerDelegate _accelDelegate;
    ...
    public override void ViewDidAppear (bool animated)
    {
        base.ViewDidAppear (animated);

        UIAccelerometer accelerometer =
            UIAccelerometer.SharedAccelerometer;
        accelerometer.UpdateInterval = 0.25;
        _accelDelegate = new MyAccelerometerDelegate (this);
        accelerometer.Delegate = _accelDelegate;
    }

    public override void ViewDidDisappear (bool animated)
    {
        base.ViewDidDisappear (animated);

        UIAccelerometer accelerometer =
            UIAccelerometer.SharedAccelerometer;
        accelerometer.Delegate = null;
    }

    class MyAccelerometerDelegate : UIAccelerometerDelegate
    {
        ...
    }
}

现在将注意力转移到第二个视图控制器及其视图。在工程中添加两个新类,一个名为SecondViewController,另一个为SecondView。SecondViewController是控制器,所以设置它的基类为UIViewController,并添加MonoTouch.UIKit命名空间。当控制器第一次加载它的视图时,将调用它的LoadView方法。之前在xib文件中定义的控制器会加载视图,因为LoadView的实现默认情况下会从xib文件读取视图。然而,为了通过代码创建控制器的视图,可以重写LoadView方法。在SecondViewController类内,添加LoadView的实现,并在实现内创建SecondView的实例,然后将它关联到控制器。在实现SecondView的同时,可以设置视图的属性,如背景颜色,代码如下:

public class SecondViewController : UIViewController
{
    public SecondViewController ()
    {
    }
    public override void LoadView ()
    {
        base.LoadView ();

        this.View = new SecondView();
        this.View.BackgroundColor = UIColor.White;
    }
}
相关文章
|
22天前
|
Linux 程序员 数据格式
【2026最新】Notepad++下载、安装和使用一篇搞定(附中文版安装包)
Notepad++ 是一款免费开源、轻量高效的 Windows 文本编辑器,支持 C/Python/HTML 等 80+ 语言语法高亮、代码折叠、正则替换、编码转换及插件扩展,专为程序员与文本处理用户打造,完美替代系统记事本。(239字)
|
12天前
|
人工智能 JSON 自然语言处理
让教学更智慧:用阿里云百炼工作流,自动生成中小学教材内容#小有可为#有温度的AI
通过可视化工作流编排,将大模型推理能力转化为标准化的教学内容生成引擎。教师只需输入教材标题和适用学段,即可自动获得结构完整、符合课程标准的章节内容,大幅降低备课门槛,助力教育资源均衡化。
494 127
|
7天前
|
人工智能 缓存 安全
Claude Code 封号真实原因曝光,这次彻底不装了,直接针对国内开发者的账号下手?
Claude Code 封号潮背后:逆向扒出客户端隐写区域标记,Anthropic 政策收紧叠加 DeepSeek 7 月涨价,国产替代更紧迫。
|
16天前
|
存储 人工智能 监控
QoderWork完全指南:从入门到精通,把“AI实习生”变成你的全能工作搭档
阿里云2026年推出的桌面端AI工作助手QoderWork,不止聊天,更可动手干活:本地运行、安全可控,支持文件整理、数据分析、PPT生成、网页开发等;内置专家套件、多Agent协作与自定义Skills,让AI真正成为你身边的“AI实习生”。
|
7天前
|
人工智能 安全 程序员
终于,Claude Code 封号的原因被曝光了!竟然针对中国用户,植入隐形代码?!
通俗易懂地揭秘 Claude Code 封号的手段,分享一些自己对 AI 编程困境的思考,Codex、Cursor、DeepSeek、智谱 GLM、甚至是豆包,都有所行动了
442 1
|
8天前
|
人工智能 安全 Cloud Native
Higress 新发布:AI Gateway 能力增强,Gateway API 及其推理扩展持续打磨
增强 AI 网关能力,持续打磨 Gateway API 及其推理扩展。
386 126
|
16天前
|
机器学习/深度学习 人工智能 调度
🐴 HappyHorse 1.1 现已上线阿里云百炼!快来查收模型使用指南,现在调用享 6 折~
HappyHorse 1.1 是新一代视频生成大模型,全面升级动态表现力、角色一致性、指令遵循、视觉质感与音画协同能力。支持I2V/T2V/R2V三类生成,适配短剧、电商广告、品牌营销等场景,提供高质、流畅、可控的AI视频生产力。
936 5
🐴 HappyHorse 1.1 现已上线阿里云百炼!快来查收模型使用指南,现在调用享 6 折~