《MonoTouch开发实践指南》一3.5 实现自定义UIView

3.5 实现自定义UIView

对于SecondView类,首先要将它设置为UIView的子类,同时添加MonoTouch.UIkit命名空间。要绘制视图,可以调用DrawRect方法。为了给视图添加自定义绘图代码,需要重写DrawRect方法。每一个iOS应用程序都有一个主循环。当给DrawRect添加代码时,它在下一次循环时才会调用。不能在程序中直接调用DrawRect方法,它只能由系统在需要的时候调用。当视图第一次加载的时候,会执行绘图代码,所以不需要额外的步骤去调用DrawRect。当视图在初始绘制后,如果要强制重画,可以调用视图的SetNeedDisplay方法,这样视图就可以在事件循环过程中进行重画。
在执行自定义绘图时,可通过视图的图形上下文(graphics context)进行绘制操作。图形上下文是用户绘图用的抽象画布(如屏幕),可在上面使用任何可用的画图工具(如颜色笔、几何形状等)进行画图。代码清单3-6列出了部分SecondView类用于绘制一个正方形的代码。
注意 视图的绘图工作实际通过层技术实现,这将在第6章进行详细讲述。
代码清单3-6 自定义绘图UIView

using System;
using MonoTouch.UIKit;
using MonoTouch.CoreGraphics;
using System.Drawing;

namespace LMT33
{
    public class SecondView : UIView
    {
        CGPath _path;

        public SecondView ()
        {
        }
        public override void Draw (RectangleF rect)
        {
            base.Draw (rect);

            // Get graphics context
            CGContext gctx = UIGraphics.GetCurrentContext ();

            // Set up drawing attributes
            gctx.SetLineWidth (2);
            UIColor.Gray.SetFill ();
            UIColor.Black.SetStroke ();

            // Create geometry
            _path = new CGPath ();

            _path.AddLines (new PointF[] {
                new PointF (110, 100),
                new PointF (210, 100),
                new PointF (210, 200),
                new PointF (110, 200) });

            _path.CloseSubpath ();

            // Add geometry to graphics context and draw it
            gctx.AddPath (_path);
            gctx.DrawPath (CGPathDrawingMode.FillStroke);
        }
    }
}

代码清单3-6中的绘图代码使用了核心图形(Core Graphics)功能,这会在第6章讲述。也可以在UIView实现中直接使用UIKit类。例如,在UIView内使用UILabel显示视图的标题,并通过提供标题(title)属性让控制器设置标题,代码如下:

...
string _title;
UILabel _titleLabel;

public string Title {
    get { return _title; }
    set {
          _title = value;
          _titleLabel.Text = _title;
    }
}

public SecondView ()
{
    _titleLabel = new UILabel ();
}

...

public override void Draw (RectangleF rect)
{
    ...

    _titleLabel.Frame = new RectangleF(5,5,Bounds.Width-10, 25);
    this.AddSubview (_titleLabel);
}

注意 如果不使用UILabel,而是使用核心图形(Core Graphics)功能直接绘制标题的字符串,那么需要在设置标题时调用SetNeedDisplay方法。尽管在初始化时看不到标题,但调用者会改变视图的标题。当更改标题时,调用SetNeedsDisplay方法可以重画视图。当更改标题时,UILabel会在内部调用SetNeedsDisplay方法。
代码中添加了一个包含标题的UILabel作为子视图。视图是按层次结构排列。当添加一个子视图到一个视图时,无论是在视图内部实现(如当前示例的UILabel),还是在外部通过控制器或IB的视图类实现,按照z次序放置子视图都会位于其父视图的上方。如果现在运行应用程序并选择第二个标签,将会看到绘制有标题和正方形的屏幕(如图3-11所示)。
在该示例中,标签使用了Frame属性和父视图的Bounds对象来设置其大小和位置。Frame属性将视图的大小设置为一个矩形,它的位置则由父视图坐标系中的点决定,而边界则由视图自己坐标系的大小和位置决定。通常情况下,Frame属性用来设置视图实例的大小和位置,而不是在一个实际的视图实现中作为边界使用。例如,在该示例中使用UILabel的实例,而不是SecondView的实现。在该示例中,父视图就是secondView。设置UILabel的Frame属性,定义矩形的大小和位置是以父视图的原点为测量点的。iOS坐标系的原点在左上角,往右就是+x,往下就是+y。
注意 在设置视图的Frame属性时,它实际上并不存储在视图内,而是用来从内部获得其他值,如边界。同样,这将在第6章中讲述。
视图要做的另外一件事情就是捕捉事件,如触碰事件。如果检查代码清单3-7中的UIView的类层次结构,就会看到它派生于UIResponder,除此之外,还定义了几个虚函数用来处理触碰事件。为了演示这一点,现在在视图中添加一个简单的命中测试以检测用户是否触碰了正方形。
代码清单3-7 UIResponder使用虚函数处理触碰事件

public class UIResponder : NSObject
{
    ...
    public virtual void TouchesBegan (NSSet touches, UIEvent evt);
    public virtual void TouchesMoved (NSSet touches, UIEvent evt);
    public virtual void TouchesEnded (NSSet touches, UIEvent evt);
    public virtual void TouchesCancelled (NSSet touches, UIEvent evt);
    ...
}

要判断是否触碰了正方形,需要重写UIView子类的TouchesBegan方法,详细代码请看代码清单3-8。为了简单起见,这里只处理单一的触碰。触碰点封装在UITouch类中。要找到视图的实际触碰点,可以调用UITouch对象的LocationInView方法,它将返回视图坐标系内的点。
代码清单3-8 在UIView子类中处理触碰事件

public override void TouchesBegan (NSSet touches, UIEvent evt)
{
    base.TouchesBegan (touches, evt);

    UITouch touch = touches.AnyObject as UITouch;

    if (touch != null) {
        PointF pt = touch.LocationInView (this);

        if (_path.ContainsPoint (pt, true)) {
            Title = "You touched the square";
        } else {
            Title = "You didn't touch the square";
        }
    }
}

之前使用核心图形的路径功能来绘制正方形。在路径中有个ContainsPoint函数可以用来执行命中测试,将UITouch返回的点传递到该函数,它告知点是在路径组成的正方形内还是在正方形外。然后就可以通过标题将结果输出给用户(如图3-12所示)。

时间: 2024-09-20 05:56:27

《MonoTouch开发实践指南》一3.5 实现自定义UIView的相关文章

《MonoTouch开发实践指南》一导读

前 言 欢迎阅读本书.如果你是一个.NET开发人员且有兴趣开发基于iOS设备的本地应用程序,那么MonoTouch是个不错的选择.它在优雅的C#和.NET中融合了CocoaTouch框架和Objective-C语言概念,让其成为一个精心设计且乐在其中的技术.可以使用MonoTouch,在App Store和企业中部署应用程序(假设具有适用的许可证).甚至只需要一个免费版本的模拟器,就可以学习和尝试它,而不需要任何额外的费用.此外,如果你是一个学生,还可以使用带有折扣的学生版本. MonoTouc

《MonoTouch开发实践指南》一2.3 MonoTouch的工作原理

2.3 MonoTouch的工作原理 MonoTouch使用静态编译方式将代码编译为ARM二进制代码.使用MonoTouch创建的每一个应用程序都是独立的,也就是说,应用程序所需要的东西都要打包,之所以这样,是因为iPhone不允许使用共享库.MonoTouch通过绑定方式向C#公开iPhone的原生库,因而不需要在语言之间做转换.通过静态编译(Ahead-Of-Time,AOT)生成ARM二进制代码,MonoTouch应用程序就可满足发布应用程序到App Store的所有必需条件. 注意 在写

《MonoTouch开发实践指南》一1.1 搭建开发环境

1.1 搭建开发环境 在使用MonoTouch开发之前,有许多事情需要先验知识(priori).首先从苹果(Apple)入手获取所需要的一切,然后过渡到必不可少的MonoTouch上. 1.1.1 安装iOS SDK和苹果开发工具 欢迎来到使用.NET进行iOS应用开发的世界.我敢肯定,你现在会兴奋得想立刻开始编写程序,不过,首先要做的是在手头那部闪闪发亮的Mac上搭建开发环境.然后熟悉一下在模拟器和iPhone上进行开发所需的所有步骤以及应用程序如何在它们中运行.注意 本书的内容也适用于iPo

《MonoTouch开发实践指南》一第3章-3.0 视图和视图控制器

第3章-3.0 视图和视图控制器 3.1 构建MonoTouch MVC应用程序 3.2 在IB中使用视图和控制器 3.3 为视图控制器及其视图添加功能 3.4 使用多个视图和控制器 3.5 实现自定义UIView 3.6 小结 MonoTouch和CocoaTouch的基础是基于一些基本类和模式建立起来的.本章将讲述如何在MonoTouch中根据这些模式使用基块类来构建应用程序,这些基块类是UIKit.UIView和UIViewController的一部分.

《MonoTouch开发实践指南》一1.2 创建MonoTouch应用程序

1.2 创建MonoTouch应用程序 在本节中,将编写一个带有标签和按钮的简单应用程序,并通过单击按钮来改变标签的文本显示.完成后的应用程序将如图1-10所示. 1.2.1 创建用户界面 首先要做的是创建用户界面.返回刚才在MonoDevelop创建的包含一个空白窗口的应用程序,如果IB还没打开,双击MainWindow.xib文件打开IB.前面提及过,IB是苹果的用户界面设计工具,可以用它来创建应用程序的界面.如果曾经进行过Windows或ASP.NET开发,就会觉得它的作用有点类似于Vis

《MonoTouch开发实践指南》一2.2 通过示例将Object-C与MonoTouch进行对比

2.2 通过示例将Object-C与MonoTouch进行对比 下面通过示例来说明上面讲到的一些概念.前面提到的UIActionSheet将会在示例中使用.通过Objective-C与C#的对比,将有助于清楚地了解如何使用MonoTouch开发应用程序. 注意 通常,使用MonoTouch开发应用程序不需要Xcode或Objective-C,这里这样做的目的是作为基础知识辅助说明MonoTouch的设计.如果有兴趣想了解更多的相关技术,推荐阅读Stephen G. Kochan写的<Progra

《MonoTouch开发实践指南》一3.1 构建MonoTouch MVC应用程序

3.1 构建MonoTouch MVC应用程序 使用UIKit的MonoTouch应用程序通常都使用UIView和UIViewController来构建.这些都是用于构建模型-视图-控制器(Model-View-Controller,MVC)设计模式的iOS应用程序的主要类. 将应用程序的特定领域(Domain Specific)信息和应用程序的显示分离开来,通常会给应用程序带来好处.这种设计模式可以帮助开发人员在面对不断变化的功能需求时保持基础代码的稳定,有助于促进代码重用,并使构建单元测试的

《MonoTouch开发实践指南》一2.1 iOS SDK概述

2.1 iOS SDK概述 MonoTouch以iOS SDK为基础,通过开发工具MonoDevelop和它与IB的集成,增加对C#语言的支持.而且,它是基于Mono的.NET实现的,因而带来了许多类库,支持现有的代码以及垃圾回收机制..NET开发者会觉得与Mono.MonoDevelop一见如故,但除非之前有使用Objective-C和Xcode进行Mac或iOS开发的经验,否则会对iOS SDK和它在MonoTouch中的实现感到陌生.本章将介绍iOS SDK和MonoTouch的工作原理.

《MonoTouch开发实践指南》一第1章-1.0 Hello,MonoTouch

第1章 Hello,MonoTouch 1.1 搭建开发环境 1.2 创建MonoTouch应用程序 1.3 在设备上进行开发 1.4 使用MonoTouch调试器 1.5 小结 本章将介绍MonoTouch的开发环境.首先讲述搭建开发环境的所有步骤:然后创建第一个MonoTouch应用程序,并介绍MonoDevelop这个IDE开发工具和调试器:最后讲述如何将设备配置为开发部署设备.