一.view分层

(1)View的结构是分层的,一个view只能有一个父view,但可以有多个子view。子view的顺序是相关的,在数组中的位置越高或者说数字越大,就显示在后面,位置低的显示在前面。顶层的在后面,底层的在前面。view可以重叠。

(2)最顶层的view是管理屏幕的controller的view。如果mvc的view是另一个controller,通常会有一个controller的view是整个屏幕,其他细节就交给其他controller。

可以用代码实现view分层,有2个重要代码: (1)addSubview是往一个view里添加子view。 (2)把一个view移除,不能要求同一个view移出刚刚添加的view,要去到那个view,让它移除它自己。 总结:通过父view添加子view,但是移除要通过子view自己。

二. view coordinates

view是个坐标系统

(1)CGFloat,图形化编程时要用CGFloat,不用float或double

CGPoint、CGSize、CGRect定义:

struct CGPoint     

 {   float x;     

     float y;  };
 struct CGSize     

  {   float width;    

      float height;   };
 struct CGRect

 {   CGPoint origin;

      CGSize size ;   };

(2)view的坐标系统原点在左上角,增加x是向右的,增加y是向下的。

(3)坐标单位是点而不是像素。点是图形上的术语,UIView上有个property叫contentScaleFactor,它会返回一个点有多少像素。编程时只要使用点就可以了,通常不需要知道像素,ios会处理好,比如字体会自动做平滑处理。

(4)views有3个和位置大小相关的property:bounds、center、frame, bounds是个矩形,它是view自己的坐标系统下的绘画区域,所以如果在你自己的绘图实现中,你创建了个自定义的view,当你绘图的时候,只会用到bounds。此时不要在view的实现里面用另外两个property,别管原因只要这么做就行了。

center和frame是在父view坐标系统中你的view的中心点和容纳view的矩形,所以这两个只用来在父view中定位你的view。center和frame是连在一起的,你设置了center会移动frame,设置frame也就设置了center。

永远不要在view的实现里用frame和center,这两个是用来定位的。

三. Custom Views(自定义views)

什么时候需要创建自己的UIView子类?view是用来控制绘图和触摸事件,所以就是当你需要绘制图形或想要控制触摸事件的时候。我可以继承UIButton吗?(因为我主要需要的就是UIButton那样的东西,只是点击事件的处理会不同。)答:通常情况下的建议是不要继承这些内置类型,它们只被优化为拖出来用,而没有优化过继承和重载。我只是建议而不是要求你们不要去这么做,不是做不到,它们也是对象可以被继承,但只是建议你不要这么做。

怎么去绘图呢?你有了view的子类,很简单只要重载方法drawRect。注意:永远不要去调用drawRect,系统会去调。

怎么告诉系统需要重绘呢?答:发送这两个消息setNeedsDisplay和setNeedsDisplayInrect。可以认为初始化的时候设置的是一个点(0,0,0,0),然后晚些时候系统查看所有需要重绘的东西,把他们按顺序排列因为有些东西可能会重叠,然后再非常高效地把需要画的东西绘制出来,这样做有两个好处,一是让系统依据层的情况最优化性能,二是如果你的property有一些setter,当你设置的时候需要重绘,这种情况也被最优化了。所以你所有的setter都会调用self的setNeedsDisplay来重绘。如果有人用了你的view,然后调用了好几个这些setter,只要重绘一次,每个setNeedsDisplay都被一起传过去,然后一次性画出来,而不是每次都重绘,导致不停地在绘图,绘图开销非常大。想一下绘图时会发生什么,最起码会把内存中的一些东西移到另一个位置,移动需要执行很多的指令,尽管图形系统已经是不可思议的快了,但是开销仍然非大。举个例子,我们前面做的计算器,注意到当我们执行一个计算的时候,我们对其入栈。对栈做了一个不可变的副本,又再把它变回可变的完成这样一个过程需要执行的指令和高亮一个点中的按钮比起来根本不算什么。强调一下,我不希望你们调入陷阱里,你看到一个东西效率不高,就拼命去优化它,你这么做不是去考虑时间到底花在哪了,就叫做premature optimization,不要这么做,我不希望看到你加了50行代码优化还花不到1%处理器性能的东西。

写代码的信条就是代码行最优化、最少bug、最容易写、最容易读,这种代码就是你不需要写的代码。代码越少越好,设计数据结构实现方法的时候,代码越少越好。

怎么实现自己的drawRect? 答:用Core Graphics Framework,它的API是C语言的,是非面向对象的。过程:创建一个环境(context),然后创建一些轨迹(paths)比如直线和弧线,再设置他们的字体颜色式样等并描边(strock)或填充(fill)到轨迹里。

绘制文字和轨迹是一回事,都是由细线组成的,系统会为我们做好。绘制图片就是复制二进制码。

1.Context

(1)环境(context)决定了在哪绘图。context种类有:Screen、OffscreenBitmap、PDF、Printer。所以创建环境的方法决定了要在哪绘图。

(2)对于普通drawing,当调用drawRect时进到drawRect后会调用一个C函数,UIKit会给准备绘图的环境。 (系统可能是要打印,当打印的时候你会在drawRect发现打印的内容,可能是要打印个大东西,但是得到的环境的方法是一样的。) 注意,每次调用drawRect环境都是不一样的,所以不要把它保存起来,而是每次都去获取新的。

(3)drawRect中有下面的C函数得到当前context,这句代码也几乎是每个drawRect的第一行。

CGContextRef context = UIGraphicsGetCurrentContext();//CGContextRef是

//个cookie,不知道到底是什么,它不是个对象,因为没有*号。调用这行代码就会得到context。 

2.Define a Path(怎么去绘图,下面演示的只是原理)

在描边或填充之前,还可以设置图形属性,上面用了UIColor设置颜色,注意在用UIColor的时候不需要指出它的环境,当在使用对象的时候,事实上只用到UIColor、UIFont、NSString。这里使用对象的时候不用指出它的环境,它会假设你用的是当前环境,只要在前面的CGContex表面环境就可以了。设置了描边和填充后,还是什么都没画,调用CGContextDrawPath之后就画上了,其中的kCGPathFillStroke是常量标志,表示描边和填充或仅描边或仅填充。上面的代码既描边又填充,所以看到图上是红色描边,填充是绿色。

其实还可以保存轨迹(path),用完之后还能交给其他环境继续使用。和前面讲的类似,只是用CGPath代替CGContext而已。为什么需要保存轨迹呢?可能你建了个星星的轨迹,然后你需要画100个。

3.Graphics State

(1)UIColor

UIColor 有些类方法比如redColor,会返回很多的标准色,当然UIColor还有很多初始方法来创建一个颜色,比如initWithRGB。还可以setFill和前面的填充一样或者就是set,就是既描边又填充。这就是UIColor的用处,设置描边和填充。

(2)透明度(alpha)

UIView可以设置透明的东西(虽然不常用),透明度0是完全透明,1.0是完全不透明。

UI还可以对整个view设置透明度,所以原先不透明的view,设置alpha为0.5,那整个view就变成半透明了。

事实上,还有另一个方法,设置隐藏属性(property hidden).隐藏(hidden)表示view仍在层级结构中,但是不显示也不响应,点击就好像它不在view里面,但它确实在那。hidden挺常用的,比如在一个小屏幕上,如果一个view暂时用不着,那就先隐藏掉,等又要用到时候再取消隐藏。 you can hide a view completely by setting hidden property:

@property (nonatomic) BOOL hidden; 
myview.hidden = YES;//view will not be on screen and will not handle events

  隐藏的开销比透明少一些,但系统很智能。全透明和隐藏是差不多的。view可以重叠,你可以用透明实现特效,特别是对于动画来说,比如渐进渐出。

注意:透明的开销不小。两层的融合比覆盖的开销要大很多。

(3)Graphics State(图形状态),用的最主要的是颜色,但也可以用一些复杂的比如线宽、图案填充等如下图所示,stanford本门课程不讲。

(4)Graphics State有一点要小心,就是subroutines(子程序)。比如我有了一个环境,然后设置它的图形状态,那么这时候我调用的子程序会怎么样呢?子程序里面也有自己的图形状态,这就和我的设置冲突了,所以对此有个机制,叫push和pop环境。push和pop非常高效,所以不要担心性能。

如上图,如果你有个drawRect用了刚刚的drawGreenCircle画了些红色东西,再画了绿圆,再接着画红色。 如果画绿圆之后我再画的也变成绿色就非常不好了。所以使用push和pop就是为了分隔开来。

4.Drawing Text

(1)用UILable来draw text

(2)如果自定义的view需要自己draw text

如上图所示,方法是首先要有个字体对象UIFont,然后调用NSString的一个方法去绘制,这应该会使你困惑,因为NSString所在的foundation不是一个UI相关的东西,它的foundation和数组字典什么的意义,不应该有绘图的东西。那么它为什么会出现在这里?因为字串是你想要绘制的东西,你有字串你想要把其中的文字画出来,如果只要发个消息给字串就能画出来不是很好吗。那这到底是怎么工作的呢?答案是UIKit,foundation不同的一个东西,它添加了绘制字串的方法,然后通过obj-c的一个叫范畴(category,书上也有叫“类别” )的机制加回到NSString里去,因为UIKit在为另一个framework里的东西添加内容,我们这里不讲继承什么的,它就是把方法添加过去了。范畴不能滥用,它也可能会导致你添加的方法已经被实现了,这就有点竞争的意思了。本门课程会大范围的使用范畴,因为范畴在它擅长的事情上非常好用。如果用在不该用的地方就很糟,用在该用的地方就很好。

当你要画个文字,只要发个消息给NSString,比如drawAtPoint:WithFont:,所以你知道字体知道坐标,就能画出来了。

5.Drawing Images

(1)用UIImageView来draw images。就相当于用于图片的UILable,拖出来之后加入图片,调整大小等属性。

(2)如果你想要在drawRect里画图片,不通过另一个view。即,Create a UIImage object from a file in your Resources folder,最常用的是直接拖图片到Xcode的resource文件夹,再直接通过图片名调用。还可以通过文件系统获取或者通过网络传过来的二进制数据(raw data),还没学到文件系统,学过NSData。

(3)还可以通过context之类的东西自己创建图片,先begin,画好后从context获取出来,最后end 。 上面讲的三条见下图

所以有很多方法去获得UIImage,一旦获得之后,在你的drawRect里可以用这些方法画出来:

drawAtPoint会按原大小绘图,drawInRect会缩放图片,drawAsPatternInRect会重复绘图以填满指定的矩形区域。 你还可以用PNG或者JPG格式的二进制数据来表示图片.

[Stanford 2011] Views 知识点的更多相关文章

  1. [Stanford 2011] 知识点小结

    1.获得帮助:option+click /  option+double click 2.@property里的nonatomic,表示非原子性访问,atomic是obj-c里使用的一种线程保护技术, ...

  2. [Stanford 2011] Ordinary Calculator(By myself)

    说明: 前面的RPN计算器是按照stanford课程做的,是后缀表达式的计算.现在这个计算器是自己做的.这个是一般的计算器,即中缀表达式的计算,而且把计算过程也显示在屏幕上, 设计方法: 在Model ...

  3. [Stanford 2011] MVC introduction

    以下是课程笔记,仅供以后复习之便. 1.什么是MVC? (1) Model:如飞机激战的游戏中,太空中的飞船,什么机型,每个飞船有多少机枪,多少护甲,这些硬件组成是model. (2)Controll ...

  4. (转) Awesome Deep Learning

    Awesome Deep Learning  Table of Contents Free Online Books Courses Videos and Lectures Papers Tutori ...

  5. What are some good books/papers for learning deep learning?

    What's the most effective way to get started with deep learning?       29 Answers     Yoshua Bengio, ...

  6. python 学习第二十一天,django知识(三)

    一,django的url路由系统总结 1,url(/index/,函数或者类) 2,url(/index/(\d+), 函数或者类) 3,url(/index/(?P<nid>\d+),函 ...

  7. mvc3 学习链接收集

    原文发布时间为:2011-04-17 -- 来源于本人的百度文章 [由搬家工具导入] The mvc3 study links collection http://dotnetslackers.com ...

  8. 2011斯坦福大学iOS应用开发教程学习笔记(第一课)MVC.and.Introduction.to.Objective-C

    blog.csdn.net/totogo2010/article/details/8205810  目录(?)[-] 第一课名称 MVC and Introduction to Objective-C ...

  9. [C#项目开源] MongoDB 可视化管理工具 (2011年10月-至今)

    正文 该项目从2011年10月开始开发,知道现在已经有整整5年了.MongoDB也从一开始的大红大紫到现在趋于平淡. MongoCola这个工具在一开始定位的时候只是一个Windows版本的工具,期间 ...

随机推荐

  1. 初识view

    屏幕左上角为原点,向右为 x 轴, 向下为 y 轴. getLeft getTop getRight getBottom 分别返回 view 的左上右下的坐标,这里的坐标都是相对于view的父view ...

  2. 51nod 1165 整边直角三角形的数量

    1165 整边直角三角形的数量 直角三角形,三条边的长度都是整数.给出周长N,求符合条件的三角形数量. 例如:N = 120,共有3种不同的满足条件的直角3角行.分别是:{20,48,52}, {24 ...

  3. 跳舞毯[XDU1005]

    Problem 1005 - 跳舞毯 Time Limit: 2000MS   Memory Limit: 65536KB   Difficulty: Total Submit: 308  Accep ...

  4. Transactional topologies —— 事务拓扑

    事务拓扑是怎么回事? Storm guarantees that every message will be played through the topology at least once. St ...

  5. POJ 2486 Apple Tree(树形DP)

    题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...

  6. eval(gzinflate(base64_decode N层,自动解密

    <?php header("Content-type: text/html; charset=utf-8"); $decode = 'DZdFEsRWEkT3vojt0EJM ...

  7. 矢量图标转成16*16大小的SVG格式

    著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:一一链接:http://www.zhihu.com/question/32233782/answer/68629385来源:知 ...

  8. pod 安装 Masonry 遇到问题

    pod 导入第三方库 Masonry: 在工程masonryTest的文件下新建一个Podfile文件 编辑如下内容: platform :ios, '8.0'xcodeproj 'mansoryTe ...

  9. 相关css 细节处理 neat.css

    人性化的细节处理 例如: textarea 默认只能垂直拖动,防止宽度改变破坏布局. textarea { resize: vertical; } 汉字字号小于 12px 不易阅读,为 <sma ...

  10. dragloader.js帮助你在页面原生滚动下实现Pull Request操作

    dragloader.js是一个面向移动Web开发的JavaScript库,帮助开发者在使用页面原生滚动时,模拟上/下拉手势,实现Pull Request操作. 在移动设备上,一般会使用 drag d ...