iOS UI 框架

来源:互联网 发布:福建广电网络收费价格 编辑:程序博客网 时间:2024/04/30 14:47

UI阶段

 pastedGraphic.png

一个视图里面可以有多个子视图,每个视图只有一个超视图,这就构成视图的层次结构.该结构允许视图一并出现和消失,基本体现了响应链.


从内存管理的角度讲,父视图总是保留(retain)它的子视图,所以子视图可以release自己.当不希望一个视图出现在窗口上时,可以调用UIView.hidden=YES. //hiden隐藏


既然视图是窗口上的一个区域,那么视图就有位置,大小.

pastedGraphic_1.png


获取信息:

CGPoint:{x,y}坐标信息//视图所在的坐标信息

CGSize:{width,heiht}宽度和高度//视图所在的大小信息


CGRect:{origin,size}上面两个结构的综合//视图所在的坐标和大小信息,坐标市指视图最左上的点的位置,(50,50),宽度200,高度100.


设置信息:

CGPointMake(x,y)

声明位置信息;

CGPoint point = CGPointMake(50.0,50.0);

Ponit.x=50.0;

Point.y=50.0;


CGSizeMake(width,heiht)

声明大小信息;

CGSize size=CGSizeMake(200.0,100.0);

Size.width=200.0;

Size.heught=100.0;


CGRectMake(x,y,width,height)

声明位置和大小信息;

CGRect rect=CGRectMake(50.0,50.0,200.0,100.0);

Rect.origin.x=50.0;

Rect.size.width=200.0;


视图位置和大小有两种表示方式:

一种是Frame(框架),即按照父类视图为起点.

另一种是Bound(边界),按照它自己为起点.


当创建一个视图时,往往采用Frame方式;当旋转一个视图或者处理视图事件时,大多采用Bound方法.



窗口:

视图层次结构的最高层市应用窗口.应用程序应该只有一二主窗口,它占据整个屏幕形成背景,幷是所有可见视图的父类.



子类和父类的视图要点:

1:如果视图从超视图中删除或在其中移动,它的子视图也会随着删除或移动.

2:如果视图大小改变,其子视图大小会自动改变.

3:子视图继承父视图的透明度.

4:视图可以限制子视图的绘制:子视图中超出父视图的部分不可见,这就是剪裁,可以在父视图的clipsToBounds属性上设置.

5:超视图拥有它的子视图(类似一个NSSAry拥有它的元素),在内存管理上,超视图retain子视图,当不再是其子视图时,要负责释放他们.


Subviews是一个UIViews的NSSArray,由后到前的顺序放置.

                  



先不管原理,先上手.

课时:

建立工程选择iPhone应该分辨率不同,用户体验不同.

所有的应用都是全屏的.


最上面的一条是状态栏,有些应用是带状态栏的.

游戏一般都不带状态栏.


横320,竖480(3GS);

4/4s 横640,竖960;


像素点是4倍.


分辨率和屏幕大小没有必然关系.


Ipad:

1024*768;

2048*1536;


Mac:

1440*900;

2880*1800;


所有设计程序都是参照320*480上.(3GS)


系统是自动缩放的10像素变成20像素.但是就像发布会说的,大小没变,原来1毫米的地方现在还是1毫米(像素填充).


按钮是矢量图.(指令)

照片是位图.(像素)


按钮上贴了图片就不行了.(图片缩放)


Sound.png 32*32

Sound@2x.png 64*64

系统会自动检测

状态栏 320*20


一般应用程序有且只有一个window.

Window和view不同.

View是块画布,有画布才能摆放控件,切换页面等;

但不是所有的view都是画布.


Window是画板,view是画布.

切换页面是抽取画布.




目前建立工程都是基于view的.


坐标系:


结构体:

CG代表核心图形库

CGPoint

CGSize

CGRect


控件等都是矩形


Window和屏幕一样大.

画布就是看到的实际大小,并没有被遮挡.(320*460)

CGPoint是点(浮点类型,x,y);


CGRect:描述一个矩形



CGPoint是左上角的左边,CGSize是大小(宽和高)

CGRect就能描述一个控件


类UIView

(UI打头是系统提供)

继承NSObject

XXMake:函数传参数返回结构体变量.

CGRectMake(4个参数)


控件等可以超出屏幕,但没意义.


UIView里有2个属性声明:

@property(nonatomic)CGRect frame;

@property(nonatomic)CGRect bounds;

默认是直接赋值.

(retain等用在OC对象,这里是结构体)


看得见的都是直接或间接继承UIView.


Viewb放在viewA上,A成为B的父视图.B是子视图.

父视图对子视图是强引用.(数组对元素的管理)

viewB也能指向viewA,但是 是弱引用.


CGRext(X,Y,宽,高);


一般从父视图角度去看坐标.(superView)


pastedGraphic_2.png

这里继承的原因是要复写函数.


画布和用户交互要视图控制器来管理.但多个页面就很乱了.

画板就一个,画布很多.

一个画布就对应一个控制器.(刀片式服务器)

视图控制器对画布是强引用.(内有指针)

一般控制器都是UIViewController的子类

视图控制器先被创建.

被视图控制器管理的对象才是画布.

切换页面是换了全新的控制器和画布,很方便.


viewDIdload//字面意思:画布加载完毕

是看不到在哪调用的,UIViewController的复写.

自动触发,一旦当我们画布铺好后,此函数就立即被触发.

所有给画布放东西的基本都在此函数,也成为初始化函数.

pastedGraphic_3.png

涉及到初始化的函数,都必须要先初始化父类.(如果父类有东西的话,就体现好处了.)


pastedGraphic_4.png

viewController的对象去调用的,self就代表它.

前面的.是OC的读.view是controller的属性.

后面的.是OC的写.

pastedGraphic_5.png

pastedGraphic_6.png

自己写的Viewcontroller类继承于UIViewController.它里面有个属性.

@property (nonatomic,retain)UIView* view;


UIView类里有个属性.

@property(nonatomic,copy)UIColor* backgrounderColor.



[[self view]setBackgrounderColor:XX];

原理是这里调用的.


RGB:三原色

colcWithRed:

红:绿:蓝:(浮点,0~1)

alpha:是管理透明的.(浮点,0是透明的)

这是UI工程师调配的,不是程序员管理的.

pastedGraphic_7.png

创建结构体变量.

参照画布的坐标系去创建.

pastedGraphic_8.png系统的类

只是静态的呈现,无法交互.(其实可以,touch事件,比如隐藏键盘)


pastedGraphic_9.png

initWithFrame是在UIView类里定义的.


pastedGraphic_10.png

初始化Frame;

几乎初始化所有的控件.

强引用.


pastedGraphic_11.png

addSubview是UIView里的函数,作用是放到画布上.

把label作为子视图放到父视图.

View会对label增加所有权.

只要完成父视图和子视图绑定就会变成强引用.


目前label有2个拥有者.

View和指针.


背景色是UIView的属性,label也就具有.


pastedGraphic_12.png

系统提供的属性就不用手动释放.

自己声明的就必须要.


pastedGraphic_13.png

控制label显示的内容.UILabel的属性.


pastedGraphic_14.png

也是UILabel的属性.

用来控制label的字体颜色.


pastedGraphic_15.png

字体对齐属性.

pastedGraphic_16.png

它是个枚举.(左对齐,中间,右对齐)


pastedGraphic_17.png

字体和大小.

pastedGraphic_18.png



pastedGraphic_19.png

整个画布和label的实现.


pastedGraphic_20.png






有图层的概念,2个label会覆盖,创建有创建顺序.


pastedGraphic_21.png

这两个并不是子父类的关系,地位是同等的.


改变图层顺序的函数

insertSubview:label atIndex:0;把子视图插入到0这个下标.

(并没有下标的概念)

画布管理label,用类似可变数组的变量去管理存储.

pastedGraphic_22.png


我们添加子视图是有层次的概念的,类似于的PS的图层概念.




pastedGraphic_23.png

不写的话,默认是nil(text指针)



创建button对象:

创建的时候要先创建类型,创建后无法修改.

pastedGraphic_24.png

pastedGraphic_25.png

最常用的是圆角按钮.

这里是弱引用.(buttonWithType是+)


contactAdd是自定义,要贴图的按钮.



pastedGraphic_26.png

创建按钮大小;


和创建Label的区别在于类型,创建后无法修改.



pastedGraphic_27.png

给按钮增加文字;

按钮分2种状态,按下状态和正常状态.

函数setTitle:文字 forState:状态;



UIButton->UIController->UIView(继承)



响应按钮上的事件:

关键在于无法确定什么时候去响应,只有在按下的时候才去响应.

程序员无法知道.


回调函数的概念:

在没有发生之前,就预先规定了什么情况下调用什么.(应急预案)

操作系统帮忙调用(系统知道用户按下了什么按钮)

自己不调用的函数.(回调)


参数是button对象.

谁触发就把谁传进来.(按钮)


pastedGraphic_28.png

名字自定义的;


函数写好了,该绑定函数:



pastedGraphic_29.pngpastedGraphic_30.png

绑定函数.


手指离开按钮有2种可能,在里面离开的(按下和离开的时候手指都处在里面,优点是可以取消),在外面离开的(按下在外面离开)


@selector是关键字,作用是转换成函数的真实地址,不然平时并不是真实的地址.pastedGraphic_31.png

这样是代表了地址.

Self是控制器对象本身.

此函数的意思是:当button这个按钮产生了TouchUpIndside事件后就要去调用addButtonPressed函数.



pastedGraphic_32.png

绑定事件的函数.




pastedGraphic_33.png

取出当前字符串并转换成int;

pastedGraphic_34.png

++后,在格式化字符串(回填);


属性(函数)和成员不同.属性是对外开放的.


pastedGraphic_35.png

响应代码;



取得按钮的标题:(用一个函数搞定多个按钮事件)

NSString* bynTitel=[button currentTitle];

用isEqualToString对比;


UIView* view=[[UIView alloc]initWithFrame:rect];

这里的view就不是画布了.(无控制器)


View里有个tag属性,是UIView类的.

默认是0;

填充数字后就是控件的身份证号码.(这样就不要另一个指针来接管label等了)

UIView* view=(UIView*)[self.view viewWithTag:100];(这里可以不用强转,如果是UILabel就要);

从画布上的子视图包括画布本身看谁的ID是100这个控件,找不到就是nil.

(如果函数调用很频繁,不推荐这样使用.这里无法使用static(运行时语言,无法在编译时确定指令))


View.frame.origin.x+=10;

不能在label上的坐标直接计算,因为不能对临时的值里的成员不能做写操作.(并没有修改真正的值,只是frame的返回值).


函数的返回值不能对它写操作,只能读.


用浮点数去比较对比,不能用if去比较(计算机的浮点数是近似的,不靠谱)

相等判断:

CGFloat f1,f2;

CGFloat t = f1 - f2;

看t的结果是否处在这个区间之内(-10的-6次方)到(10的+6次方),在的话就相等.



For循环来创建多个按钮:

类似计算器

按钮1 (40,140) 宽60 高30

水平间距30  垂直间距40

pastedGraphic_36.png

核心;

同一列的X坐标一样,同一行的Y一样.

按钮3=列号*按钮长度+水平间距;

pastedGraphic_37.png


按钮的数字:

pastedGraphic_38.png



pastedGraphic_39.png

按下什么数字就打印什么数字;

追加字符串函数stringAppendingSting;


pastedGraphic_40.png

这句不能省略,不然默认是nil,向nil发送消息没反应.


Strong等同与retain(在没启用ARC技术下);



在画布上添加和移走按钮:

弱引用和强引用的区别:

弱引用无法保证在使用期间,对象不消失.

但是这里画布还在就没问题,情况比较特殊.


移走函数:

[_showLabel removeFromSuperview];

从父视图上移走;


这里如果用弱引用的话,目前就画布一个拥有者,画布一移走就挂了,要用强引用.(没有消失,还在内存中)不然下次添加就野指针了.

pastedGraphic_41.png

判断还在画布上不:

移走里的判断函数:

If(self.showLabel.superview != nil)

Superview属性,assign,弱引用,父视图,

父视图拥有子视图.


添加里的判断:

Nil == self.showlabel.superview;


两个典型的弱引用:

代理




滑动条:

UISlider->UIControl->UIView(继承关系)


学习新的类的方法:

创建一个对象,alloc]init]

+号级别的:类似stringWithstring

继承UIView的

看有没有特殊的创建方法也没有+号级别的,没有就initWithFrame.

调用方法.




pastedGraphic_42.png

创建一个和画布一样大小的.


NSStringWithCGRect(self.view.frame);

打印坐标点.

pastedGraphic_43.png



loadView是创建画布的.UIViewControl的函数,可以复写.


pastedGraphic_44.png

pastedGraphic_45.png

一般就设置20,不用太高.



触发事件:

pastedGraphic_46.png


指定滑动范围的最小值:

pastedGraphic_47.png


最大的:

maximumValue=100;


取得当前滑动的数值:

pastedGraphic_48.png


Ios处理png是最高效的.


minimumValueImage是最小边的图片;

要显示图片,就必须转换成UIImage对象.

[UIImage imageNamed:@”文件名”];不用管路径

最大边的是:

maximumValueImage;


中间图片:

[slider setThumbImage:[UIImage imageName:@”文件名”]];


pastedGraphic_49.png

pastedGraphic_50.png

pastedGraphic_51.png

核心;



Label的问题:

Label要创建画布大小就用bounds.


Label中的字符串过长后,会有省略号.

Label的属性numberOfLines可以解决,类型整数,默认是1.

pastedGraphic_52.png

改成0 的话就是取消限定了.用来限定label最多能显示多少行.若果我们把这个属性设置为0那么就没有限制了.(前提是Label足够大)


还一个问题,一个完整的单词会折行:

折行方式:

单词和字符两种方式.(只针对英语)

Label.lineBreakMode(一种枚举)

pastedGraphic_53.png

默认是单词折行.

这个属性是用来指定label的折行方式.

一般都是用单词折行.


设置问题在屏幕的位置:

子类化UILabel.

(后期讲解)

目前用开源的Label.

开源的类(.h和.m)

上,中,下.


pastedGraphic_54.png

默认也是中间垂直位置.





弹出对话框:

UIAlertview

让用户把注意力集中在对话框,,做个决定.

不再画板上,不是子视图,单独的.


pastedGraphic_55.png

代理暂时用nil.

Alert不是画布的子视图,要用show函数去显示出来.

pastedGraphic_56.png



属性和指针的区别在于:

属性可以对外;

用.语法可以保证内存.



pastedGraphic_57.png

效果图.



要响应用户的选择:

涉及到委托和代理


Alert本身能够捕获按钮的事件(按钮在它身上,是一个整体(封装性)),但是无法响应(它不知道怎么去做).它可以充当委托者,有个协议,协议里有函数接口.

Delegate里的nil改成self,self代表代理者.(不是自己)

系统调用这个函数触发这个self(控制器对象)



Self的2种作用:

临时指针变量(一般是左值)和谁触发就代表谁.


self确定的方法:

确定出现在什么的函数,该函数谁调用.



代理:

UIAlertView  ->  协议  ->UIController

<UIAlertViewDelegate>:取名往往是委托者的名字

 充当代理后,复写函数:

pastedGraphic_58.png




关键在这句:

pastedGraphic_59.png

[_delegate alertView: self(UIAlertView的对象) clickedButtonAtIndex:0];

按钮下标和创建的按钮顺序一致.取消按钮是0,其他按钮是1,2,3...


上面的代码会出现在UIAlertView类的某个成员函数里.(该函数触发由按钮按下时决定)



得到按钮的标题:

NSString* title = [alert buttonTitleAtIndex:buttonIndex];

成员函数;

pastedGraphic_60.png

可以取得各个按钮的标题;

控件只能捕获事件,不能去实现,只能通过协议,然后代理去实现.(类似国家生产标准,产生多样性)


两个alert对象由同一个ViewController控制(2个代理者对象)

两个alert对象按钮是一样多而且按钮是一样的话,就没法用标题区分.

通过tag号可以严格区分.

If(100 == alert.tag)

{

...

}





UISwitch:

一种开关.(2种状态)

滑动改动值的的事件都叫ValueChange事件.

pastedGraphic_61.png

初始化方法被复写了,因为这个方法内部会自动创建一个合适的大小(宽和高);只有坐标有作用.


UISwitch的对象有on属性,开状态.


pastedGraphic_62.png

[Myswitch ison]方法.

BOOL类型的方法为isXX.



pastedGraphic_63.png

默认是关的状态,改变属性可以改动默认.

UIController里的属性,UIView没有

Enable属性默认是开的,可以交互.关闭就忽略事件.


pastedGraphic_64.png



同一个类里面的一个成员函数去调用另一个成员函数,用self.


控件触发的函数人为也可以触发.


pastedGraphic_65.png

pastedGraphic_66.png

两个核心部分(调色板);



pastedGraphic_67.png

这个容易忘记;


pastedGraphic_68.png

滑动显示数值.


Button完全透明够就没法和用户交互了.

当一个控件的alpha值为0 时就无法响应用户了.



电子书:

NSString类的成员方法读取文件.

路径不能用绝对路径了,在真实的手机上,没有电脑的路径.

pastedGraphic_69.png

需要一个NSBundle类对象来需找.txt文件.

涉及到沙盒问题,应用程序到底在哪个目录下,

NSBundle * bundle = [NSbundle mainBundle];

NSLog(@”%@”,[boundle bundlepath]);获取路径;

Bundle代表应用程序的集合.(一个目录下的资源集合)

mainBundle代表.app里的路径;

pastedGraphic_70.png

得到对象后用这个查询,要是没有.后面的格式就传nil;

或者直接传1.txt,后面传nil;


任意程序安装目录是全球唯一的.第三方的程序之间无法随意访问.

.app是个目录,整个程序所需的资源都在里面,这个目录就是应用程序的启动.


切页切的是NSString(大串);





pastedGraphic_71.png

NSValue类 间接管理非OC对象(包裹作用)

pastedGraphic_72.png

NSString对象调用的函数,计算要显示的字符串大小(长和高).

重点在第二个参数,限定大小,这个函数的结果计算值永远不会超过限定.不够会截断.


上下页的按钮条件判断:

pastedGraphic_73.png


pastedGraphic_74.png

核心循环,切页.


pastedGraphic_75.png

传入range数得到里的数据.


pastedGraphic_76.png

得到程序里的的文件路径.


pastedGraphic_77.png

利用循环不停的增加


电子书的要点:

要用开源的Label;

默认折行是单词折行.

每一行显示的字符串改成0,自动.

pastedGraphic_78.png这两个是配合的,才能知道超出画布的临界点,然后存入NSValue中.


pastedGraphic_79.png

NSValue和NSRange打包和解包:

pastedGraphic_80.png

pastedGraphic_81.png





栏目控件:

有多选的时候使用.选中后是视图显示.

UISegmentedControl //分段

pastedGraphic_82.png

pastedGraphic_83.png

自带初始化函数.

每一段显示的NSArray对象;大小自适应.

默认坐标是{0,0};


pastedGraphic_84.png

手动大小会影响实际效果,和UISwitch不一样.


pastedGraphic_85.png

美化函数,一般加上Style的基本都是自定义.


pastedGraphic_86.png

默认是第一个.


pastedGraphic_87.png

立体感


pastedGraphic_88.png

控制当前被选中的下标.


pastedGraphic_89.png

修改后默认启动是第二个图标.



继承UIController的一定可以和用户交互.


这也是一个ValueChange事件.


可以手动调用触发函数,一开始最好触发一次,不然打开没页面.


pastedGraphic_90.png




根据选中的下标得到标题:

pastedGraphic_91.png


UITextFiled:

文字输入:

尽量不要进行大规模输入.

无初始化成员方法;

pastedGraphic_92.png



边框类型:

pastedGraphic_93.png

默认是None;

pastedGraphic_94.png

圆滑的.



pastedGraphic_95.png

光标不在中间位置.


pastedGraphic_96.png

UIController的属性,可以调节,UIView却没有,所以Label要第三方.


pastedGraphic_97.png


pastedGraphic_98.png

底部会有文字提示输入.

pastedGraphic_99.png




取得输入的内容得到text就行了.


pastedGraphic_100.png

这个属性来用设置textFiled的提示信息.当用户输入任意内容后,提示消息就自动消失了.当没有信息时,内容又重新出现了.


输入格式:

属性:pastedGraphic_101.png

这个属性影响键盘大小写.

第一个是无,第二个是每个单词,第三个是句子,第四个是所有的.

默认是句子.

一般改动默认是关闭.




pastedGraphic_102.png

pastedGraphic_103.png

TextField属性.




自动更正:

pastedGraphic_104.png

有时会干扰用户输入.(词库跟不上)

默认是打开的,但一般都关闭.

pastedGraphic_105.png



更改默认输入的方式:


pastedGraphic_106.png

pastedGraphic_107.pngpastedGraphic_108.png

pastedGraphic_109.png

pastedGraphic_110.png

(高版本更多)




警告样式:

pastedGraphic_111.png

键盘的样式;(警告样式就是黑色半透明的)




Return键的类型:

查找键...


pastedGraphic_112.png


pastedGraphic_113.png

pastedGraphic_114.png






推倒重输(有个’X’):

pastedGraphic_115.png

有多种模式;



输入密码时,不显示明文:

pastedGraphic_116.png

安全输入.(字符串没变)



怎么去响应Done这个按键事件:

自己会捕获然后通知代理者;

pastedGraphic_117.png

指定df的代理者是ViewController;


pastedGraphic_118.png

协议中的函数;


pastedGraphic_119.png

响应return按钮的函数;


pastedGraphic_120.png

打印输入的内容.



怎么让键盘消失:

把TextFiled变成不激活.

第一响应者的身份不是固定的.

当前和用户交互的状态下控件就是第一响应者.

pastedGraphic_121.png

失去第一响应者的身份.


不管控件是不是第一响应者都不会引起崩溃.什么都不做.



pastedGraphic_122.png


pastedGraphic_123.png

Alert打印UISegmentedControl的下标和标题;








消息链:

让键盘消失,直接点非TextField部分包括Label都可以.

pastedGraphic_124.png

分两大类:

UIView(静态)

UIControl(交互)
UIControl还是UIView的子类.


Touch事件:

手指对屏幕的操作就只有:按下-移动-离开.

Touch :

began 阶段

Move阶段

End阶段


Cancel:触摸的取消(突然来电话,电话优先级最高)


Label实际收到了事件,从接收到began事件后,最终转发到ViewCtroller对象;(画布对应的视图控制器对象)


捕获touch事件:

-(void)touchesBegan:(NSSet *)touches * withEvent:(UIEvent *)event;

只捕获按下的事件;

只要手指落下就捕获;


NSSet和NSArray差不多,只不过它存的是touch对象;

一个手指就是一个UItouch对象.

多点触摸就是多个对象;

pastedGraphic_125.png

Touches传的是手指个数(touch对象)

坐标也在NSSet里面;


要从这个集合里取坐标:

UITouch * touch = [touches anyObject];

一个手指对应一个UITouch对象,2个手指同时落下的时候,那么touch里面就有2个UITouch对象.


坐标要根据参照物不同而不同;

CGPoint ponit = [touch locationInView:self.view];

参数传相对与XX的坐标;(上面是画布)

点到点后以画布的坐标确定它的坐标;












pastedGraphic_126.png

需要和开源的库配合才能显示在任意位置;




0 0