UI基础知识汇总

96
JavaLily
0.1 2017.03.12 12:02* 字数 17157

iOS的坐标系

原点是屏幕的左上角,各机型取值范围如下表所述:


UIView 视图的类(略讲)

@property(nonatomic) CGRect  frame; 尺寸   

@property(nonatomic,copy) UIColor  *backgroundColor 背景色

@property(nonatomic) CGPoint  center; 中心点位置

@property(nonatomic)CGFloat  alpha; 透明度

@property(nonatomic,getter=isHidden) BOOL  hidden; 是否掩藏

@property(nonatomic) BOOL  clipsToBounds; 超出父视图是否显示

@property(nonatomic,readonly) UIView      *superview; 父视图

@property(nonatomic,readonly,copy) NSArray *subviews; 子视图          

 - (void)addSubview:(UIView *)view; 添加视图

UILabel父类为UIView,标签,用于展示文字,用户不可以对文字进行编辑

@property(nonatomic,copy)  NSString          *text; //设置显示的文字  

@property(nonatomic,retain) UIFont            *font;  //设置文字的字体  封装的时候可以用宏定义

 @property(nonatomic)        NSTextAlignment    textAlignment; //设置文字的对齐方式

@property(nonatomic,retain) UIColor            *textColor; //设置文字的字体颜色

@property(nonatomic,retain) UIColor            *shadowColor; //设置阴影颜色

@property(nonatomic)        CGSize            shadowOffset; //设置阴影的偏移量(相对原来文字的偏移量)

@property(nonatomic)        NSLineBreakMode    lineBreakMode; //设置文字的换行方式  

NSLineBreakByCharWrapping label中比较精确的设置文字的一种换行方式

@property(nonatomic) NSInteger numberOfLines; //设置文字显示的行数, numberOfLines =0 不限制行数,默认UILabel只显示一行文字


UIFont  字体的类

systemFontOfSize 系统字体样式,并设置字号,默认字号为17

NSArray *familyArray = [UIFont familyNames];//拿到字体族的数组,数组中是字体族的名称

for (NSString *familyName in familyArray) {    //根据字体族的名称,拿到字体的名称  

 NSArray *names = [UIFont fontNamesForFamilyName:familyName];   

 for (NSString *fontName in names) {        NSLog(@"fontName:%@",fontName);    }

}



UIButton&NSTime&UIImageView

UIButton是一个视图类,继承自UIControl 间接继承自UIView,凡是UIControl子类可以接收触发事件。UIButton用于创建一个按钮,添加点击事件开发中注意的事情:把我们的button 尽量写的够大,可以=看起来不那么大,这样做的好处是方便用户点击.

常见的三种状态:

1、UIControlStateNormal 正常状态

2、UIControlStateHighlighted 高亮状态

3、UIControlStateSelected 选中状态(设置btn.selected)//大部分用在同意协议和不同意协议  btn.selected=yes,就是被选中状态常用方法

- (void)setTitle:(NSString *)title forState:(UIControlState)state;//设置title和title的颜色

- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state;//设置前景图  用的是填充方式的第二种

- (void)setImage:(UIImage *)image forState:(UIControlState)state; //设置背景图片

- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;//给button添加方法

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents

补充:

1、png格式的图片支持镂空,iOS应用中绝大多数素材都是PNG格式 

2、设置视图的标记,通过标记可以找到视图(From UIView) [self.view viewWithTag:xxx];


定时器NSTimer

 常用方法

1、+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;

timer创建方法是类方法,自动释放,离开当前函数就有释放的危险,但是如果添加为成员变量,就在dealloc释放了timer创建就启动,停止就销毁。第一个参数,表示时间间隔;target是接收消息的对象;selector是消息;user info传nil;repeats如果添NO,定时器,只工作一次,添YES,每xx秒,发送action给self一次。

2、- (void)invalidate;@property (copy) NSDate *fireDate; 

此函数标示定时器启动时间,使用[NSDate distantFuture]放在未来是停止,[NSDate distantPast])放在过去就是开始


UIImage和UIImageView

【注】UIImage和UIImageView的关系,近似于NSString和UILabel的关系。

一.UIImage的取图方式

1、通过图片姓名获取图片+ (UIImage *)imageNamed:(NSString *)name;  //会将图片读到内存中因此imageNamed的优点是当加载时会缓存图片到本地。所以当图片会频繁的使用时,那么用imageNamed的方法会比较好。

2、根据图片的路径获取图片 ,不会把图片读到内存中,先获得图片在App包内的路径NSString *path=[[NSBundle mainBundle]pathForResource:@"DOVE 1" ofType:@"png"]+ (UIImage *)imageWithContentsOfFile:(NSString *)path;imageWithContentsOfFile:仅加载图片,图像数据不会缓存。因此对于较大的图片以及使用情况较少时,那就可以用该方法,降低内存消耗

二.图片视图的基本使用常用属性:

@property(nonatomic,retain) UIImage *image; //设置静态图片

三.imageView中的图片 

方法先创建图片视图UIImageView *imageView =[[UIImageView alloc]initWithFrame:CGRectMake(xx, xx, xx, xx)];

imageView.image=[UIImage imageNamed:@“图片的名称”];

@property(nonatomic)UIViewContentMode contentMode;// default 取值: UIViewContentModeScaleToFill  拉伸填满,缺省;  UIViewContentModeScaleAspectFit 按比例填充;    UIViewContentModeScaleAspectFill 按比例填满

四.图片视图的动画效果

这个一般和+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo 放在一起用。

imageView.animationImages = array;//设置动画图片数组

imageView.animationDuration = 1.5;//设置动画时间,是全部图片切换一次的时间

imageView.animationRepeatCount = 0;//设置动画重复次数,设为0是无限次

[imageView startAnimating];//启动动画[imageView stopAnimating];//停止动画


UIView

UIView是所有视图的父类,UIView的属性和方法,就是所有视图的属性和方法  UILabel、Unbutton、UITextField、UIImageView的父类都是UIView

一.关于坐标系的属性和方法

@property(nonatomic) CGRect            frame;

@property(nonatomic) CGRect            bounds;

 @property(nonatomic) CGPoint          center; 

@property(nonatomic) CGAffinesTransform transform;        frame: 该view在父view坐标系统中的位置和大小。(参照点是,父亲的坐标系统)        bounds:该view在本地坐标系统中的位置和大小。(参照点是,本地坐标系统,就相当于ViewB自己的坐标系统,以0,0点为起点)        center:该view的中心点在父view坐标系统中的位置和大小。(参照物是,父亲的坐标系统)我个人认为,bounds稍微有点费解,稍不留神,想的多了,就会绕进去。每个view都有一个本地坐标系统。这个坐标系统作用比较重要,比如触 摸的回调函数中的UITouch里面的>坐标值都是参照这个本地坐标系统的坐标。当然bounds这个属性也是参照这个本地坐标系统来的。其实本地 坐标系统的关键就是要知道的它的原点(0,0)在什么位置(这个位置又是相对于上层的view的本地坐标系统而言的,当然最上面的一层view就是 window它的本地坐标系统原点就是屏幕的左上角了)。通过修改view的bounds属性可以修改本地坐标系统的原点位置。所以,我个人认为,bounds影响到子view的位置和大小

二、Transform 属性

UIView有个transform的属性,通过设置该属性,我们可以实现调整该view在其superView中的大小和位置,具体来说,Transform(变化矩阵)是一种3×3的矩阵,通过这个矩阵我们可以对一个坐标系统进行缩放,平移,旋转以及这两者的任意组着操作。而且矩阵的操作不具备交换律,即矩阵的操作的顺序不同会导致不同的结果。

常用的三种实现选中的方式:

1、view.transform=CGAffineTransformScale(view.transform, 0.5, 0.5); // 实现的是放大和缩小,两个浮点数,表示变形后和变形前横纵坐标的百分比

2、view.transform=CGAffineTransformRotate(view.transform, 0.2); //实现的是旋转角度变形(旋转形变),单位是弧度2*PI是一周 参数是一个浮点数,表示弧度 顺时针为

3、view.transform=CGAffineTransformTranslate(view.transform, 20, 20); //实现的是平移

由此可以发现屏幕旋转其实就是通过view的矩阵变化实现,当设备监测到旋转的时候,会通知当前程序,当前程序再通知程序中的window,window会通知它的rootViewController的,rootViewController对其view的transform进行设置,最终完成旋转。

另:frame bounds center transform 四个属性相互关联,改变其中一个,另三个也会改变。

【注】bounds origin部分是用来修改当前视图的原点坐标即左上角一点坐标,修改了这个坐标,影响的是子视图的位置。

三、关于父子视图关系的属性和方法

【注】任何视图,都可以添加到另一个视图上面,但是每个视图只能有一个父视图。也就是说一个子视图被添加到另一个视图上,会从原父视图上脱离。

【注】子视图的坐标是相对于父视图的。以父视图左上角一点为原点,缺省原点为(0,0)点。

移动父视图,因为子视图的位置是相对的,所以会一起移动。修改父视图坐标,子视图跟着动, 父视图隐藏,子视图一起隐藏。子视图的实际透明度,是父视图透明度X子视图透明度 。默认超出父视图的部分是可见的。父视图可以设置,边界裁剪,即裁减掉超出当前视图的子视图。

@property(nonatomic,readonly) UIView      *superview;//拿到当前视图的父视图    

@property(nonatomic,readonly,copy) NSArray *subviews;//这个方法是获取的子视图,以数组的形式返回    NSArray *array=self.view.subviews;    subViews这个数组中的顺序是按照子视图的层次排的,最下面的子视图就是第0个元素,最上面的子视图就是最后一个元素

四.关于同父视图的子视图的层次关系 

[view bringSubviewToFront:redLabel];  //传入子视图地址,将子视图拿到最上层      

[view sendSubviewToBack:yellowLabel];//将子视图放到最下面      

[view insertSubview:blueLabel atIndex:0];//将某个子视图,插入到某一层,这个方法中,如果subview不是view的子视图,则会添加为子视图,如果已经是子视图,则会改变层次      

[view insertSubview:redLabel aboveSubview:yellowLabel]; //同上      

[view insertSubview:redLabel belowSubview:subviews[1]]; //同上     

[view exchangeSubviewAtIndex:0 withSubviewAtIndex:2];//交换两个子视图层次

Δ五.层次与事件接收

1.父视图不能接收事件,则子视图无法接受事件。

2.子视图超出父视图的部分,不能接收事件

3.同一个父视图下,最上面的视图,首先遭遇事件,如果能够响应,就不向下传递事件。如果不能响应,事件向下传递。

六、UIView动画

【注】UIView动画只能修改关于坐标系的属性,以及色彩和透明度。

第一种动画设置方法

[UIView beginAnimations:nil context:nil];//启动UIView动画  

[UIView setAnimationDelay:0]; //设置延迟启动      

[UIView setAnimationDuration:10];//设置动画时间       

 [UIView setAnimationDelegate:self];//设置代理     

  [UIView setAnimationDidStopSelector:@selector(stopAnimation)];//设置回调方法 

[UIView commitAnimations];//设置完毕,启动动画

第二种动画设置方法

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations//+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion //+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

UITextFiled

文本输入框,用于用户输入文本信息(类似于C scanf)的UI视图

一.基础属性方法,下面列出属性方法的在工程中相关函数

textField.borderStyle=UITextBorderStyleRoundedRect;    //设置边框样式    UITextBorderStyleNone  没有    ;    UITextBorderStyleLine  线状边框  ;    UITextBorderStyleBezel 直角立体矩形(底座)  ;    UITextBorderStyleRoundedRect  圆角矩形

textField.text = @"用户名";  //设置文字

textField.textColor = [UIColor blueColor];    //设置文字颜色

textField.textAlignment = NSTextAlignmentLeft;    //设置文字的对齐方式

textField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;  //设置文字的垂直对齐方式

textField.font = [UIFont systemFontOfSize:20];  //设置文字的字体

textField.placeholder = @"请输入用户名";    //设置占位符

textField.secureTextEntry = NO;//设置密文显示

textField.clearButtonMode = UITextFieldViewModeAlways;    //设置clearButton模式    UITextFieldViewModeNever,  永不显示  ;  UITextFieldViewModeWhileEditing,  当编辑时    ;  UITextFieldViewModeUnlessEditing, 除了编辑时  ;    UITextFieldViewModeAlways,  永远显示

textField.leftView = leftView;    textField.rightView = rightView;  //设置左右视图设置左右视图的显示模式    textField.leftViewMode = UITextFieldViewModeAlways;    textField.rightViewMode = UITextFieldViewModeAlways; 

BOOL ret = textField.isEditing;   //判断textField是否处于编辑模式 

textField.clearsOnBeginEditing = YES;/*关于设置键盘样式*/   //设置进入编辑状态,立即清空文字

textField.keyboardType = UIKeyboardTypeDefault;  //设置弹出的键盘样式

UIKeyboardTypeDefault,  默认样式,可以输入一切字符;

UIKeyboardTypeASCIICapable,  可以输入ASCII码表上的所有字符即英文键盘;

UIKeyboardTypeNumbersAndPunctuation, 可以输入数字和字符的键盘,就是手提电话键盘     

 UIKeyboardTypeURL,  适合输入网址的键盘      

UIKeyboardTypeNumberPad, 纯粹数字键盘     

UIKeyboardTypePhonePad,  座机电话键盘     

UIKeyboardTypeNamePhonePad, 默认键盘,点击123会弹出数字键盘    

UIKeyboardTypeEmailAddress, 适合输入email的键盘    

UIKeyboardTypeDecimalPad, 有小数点的数字键盘    

UIKeyboardTypeTwitter,  适合输入推特地址的键盘    

UIKeyboardTypeWebSearch, 适合输入网址地址的键盘   

二、设置键盘的return键样式  

只有键盘样式为default生效    textField.returnKeyType = UIReturnKeyNext;        //  UIReturnKeyDefault,  返回    //  UIReturnKeyGo,    前往    //  UIReturnKeyGoogle, 搜索    //  UIReturnKeyJoin,  加入    //  UIReturnKeyNext, 下一项    //  UIReturnKeyRoute, 路线    //  UIReturnKeySearch, 搜索    //  UIReturnKeySend, 发送    //  UIReturnKeyYahoo, 搜索    //  UIReturnKeyDone, 完成    //  UIReturnKeyEmergencyCall, 紧急电话9、设置键盘的色彩    textField.keyboardAppearance = UIKeyboardAppearanceDefault;    //  UIKeyboardAppearanceDefault, 默认,根据设置的键盘不同,不同    //  UIKeyboardAppearanceDark    iOS7生效,深色    //  UIKeyboardAppearanceLight  iOS7生效,浅色    //  UIKeyboardAppearanceAlert = UIKeyboardAppearanceDark,10、设置大写提示,只是用于英语    textField.autocapitalizationType = UITextAutocapitalizationTypeNone;    //  UITextAutocapitalizationTypeNone,  不大写    //  UITextAutocapitalizationTypeWords,  单词首字符大写    //  UITextAutocapitalizationTypeSentences, 句子首字符大写    //  UITextAutocapitalizationTypeAllCharacters, 全部字符大写    11、设置自动纠错,适用于英文    textField.autocorrectionType = UITextAutocorrectionTypeNo;    //  UITextAutocorrectionTypeDefault, 默认,按照在设置里进行的设置    //  UITextAutocorrectionTypeNo,  不纠错    //  UITextAutocorrectionTypeYes, 纠错12、设置弹出自定义键盘    UIView * keyboardView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 200)];    //只有视图的高生效    textField.inputView = keyboardView;    13、设置弹出自定制二级键盘    textField.inputAccessoryView = label;14、becomeFirstResponder 成为第一响应者  resignFirstResponder取消第一响应二.协议中的方法- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField; //当textField将要开始被编辑,会委托代理调用这个方法- (void)textFieldDidBeginEditing:(UITextField *)textField;    //当textField已经开始被编辑,会委托代理调用这个方法- (BOOL)textFieldShouldEndEditing:(UITextField *)textField;  //当textField将要结束被编辑,会委托代理调用这个方法- (void)textFieldDidEndEditing:(UITextField *)textField;      //当textField已经结束被编辑,会委托代理调用这个方法- (BOOL)textFieldShouldReturn:(UITextField *)textField;      //当keyBoard上return键被点击,委托代理调用这个方法Δ三.监听键盘的收起和弹出//拿到通知中心NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];//添加通知中心监听的通知- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSString *)aName object:(id)anObject;//UIKeyboardWillShowNotification;  键盘将要出现时发送通知//UIKeyboardDidShowNotification; 键盘已经出现时发送通知//UIKeyboardWillHideNotification; 键盘将要隐藏时发送通知//UIKeyboardDidHideNotification;键盘已经隐藏时发送通知//去除通知    //去除需要当前对象响应的通知    [[NSNotificationCenter defaultCenter] removeObserver:self];备注://取出键盘的信息NSDictionary * userInfo = notification.userInfo;//    NSLog(@"%@", userInfo);NSTimeInterval duration = [userInfo[@"UIKeyboardAnimationDurationUserInfoKey"] floatValue];UIKeyboardAnimationDurationUserInfoKey 拿到键盘弹出时间【调试程序Bug】不知名的崩溃方法1:按照程序的执行顺序,打断点,找崩溃位置方法2:设置全局断点1)进入断点窗口2)单击Add Symbolic Breakpoint..., 输入-[NSException raise],然后按Done键。3)单击Add Symbolic Breakpoint..., 输入objc_exception_throw,然后按Done键。


UIViewController视图控制器

【MVC模式】

【注】iOS程序采用MVC设计模式为基础设计模式。即一个程序个构成,由模型,视图,控制器构成。模型(Model):非UI部分,数据的储存与管理;视图(View):UI部分,用于显示界面,与用户交互,包括接收触发事件,显示数据内容;控制器(Controller):本身不显示,用于管理视图,将视图部分,和模型部分链接起来。原则上视图不直接访问数据。

【注】使用MVC架构,视图不直接访问数据,可以便于修改,降低开发和维护成本。

【视图控制器】

一.生命周期

所谓这里的生命周期,指视图控制被加载后,首先调用的方法,其次调用的方法,到销毁时调用的方法。视图控制对象通过alloc和init来创建,但是视图控制对象不会在创建的那一刻就马上创建相应的视图,而是等到需要使用的时候才通过调用loadView来创建,这样的做法能提高内存的使用率。

二.模态视图控制器

切换是当前视图控制器,弹出形式是模态视图控制器 ,基本上系统封装具有特殊功能的视图都用的是模态化。

 SecondViewController * svc = [[SecondViewController alloc] init];   

 void (^block)(void) = ^(void){NSLog(@"已经弹出了模态视图"); };    //弹出模态视图    

[self presentViewController:svc animated:YES completion:block];   //当前显示的视图控制器,是被screen保留的,所以,如果MRC,弹出svc后,就可以在这里release svc。

[self dismissViewControllerAnimated:NO completion:nil];//关闭模态视图控制器,只有当前视图控制器确实是模态视图控制器,才能调用这个方法

三.容器视图控制器

【注】一般来讲视图控制器分为两种:普通视图控制器:管理一个页面的视图,和模型关联容器视图控制器:本身不显示,管理其他的视图控制器导航控制器标签栏控制器,称之为容器视图控制。


UINavigationController导航控制器

【注】导航控制器,是UIKit框架提供的一个容器视图控制器,用于切换拥有明确层次关系的视图。即由一级视图切换到二级视图,而不是平级视图间的切换。

【注】导航中视图控制器的层次结构,称为栈结构。(栈:先进的后出,后进的先出,叫做栈。 出栈:pop 入栈:push。队列:先进的先出,后进的后出,叫队列)

一.基本视图控制器切换

1、通过导航弹出

[self.navigationController pushViewController:svc animated:YES];  //返回上一级视图控制器

[self.navigationController popViewControllerAnimated:YES];        //返回跟视图控制器(这里指同一个导航的跟视图控制器) 

[self.navigationController popToRootViewControllerAnimated:YES];    //返回栈中的根视图控制器    它的操作等同于:1.找到当前栈中的视图控制器    NSArray * array = self.navigationController.viewControllers; 2.取出需要的视图控制器    UIViewController * vc = array[0];3.pop到该视图控制器    [self.navigationController popToViewController:vc animated:YES];

self.navigationController.viewControllers 里面装了我们容器里面的所有视图,数组里面的顺序就是UINavigationController(容器)里面的顺序。

2、在AppDelegate代理中必须要写的

self.window=[[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];    

self.window.backgroundColor=[UIColor clearColor];    

[self.window makeKeyAndVisible];        

FirstViewController *fvc=[[FirstViewController alloc]init];    

UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:fvc];    self.window.rootViewController=nav; 

注意:代理和block的反向传值。if(string.length>0)判断是否为空字符串;if(string)判断是否为空,扣号里值为真,因为还是是字符串

#define KWS(weakSelf) _weak _typeof(&*self)weakSelf=self //block 把强强引用转化成弱引用, 在代码中用block 反向传值可能会出现报警

【注】导航控制器发生作用,有三个类共同作用UINavigationController,本身并不显示无需定制;UINavigationBar,属于导航控制器(子对象),需要定制UINavigationItem,显示到导航条上,属于每个导航中的视图控制器,每个视图控制器有自己的BarItem,需要每个页面单独定制。

1.UINavigationBar (导航条,普通视图控件,父类为UIView)

每个导航控制器有且只有一个导航条,所有的视图控制器共用一个导航条。导航控制器中的导航条高度固定44。

(1).拿到导航条的方法:self.navigationController.navigationBar

(2).设置导航条的风格:self.navigationController.navigationBar.barStyleUIBarStyleDefault       // 默认下面三中iOS7之后几乎一致    UIBarStyleBlack、UIBarStyleBlackOpaque、UIBarStyleBlackTranslucent 设置导航条的风格样式会波及到状态栏

(3).设置导航条的背景图片:- (void)setBackgroundImage:(UIImage *)backgroundImage forBarMetrics:(UIBarMetrics)barMetrics //UIBarMetricsDefault 对应iPhone竖屏(人像模式) ;UIBarMetricsLandscapePhone 对应iPhone横屏(风景模式)

(4).是否隐藏导航条:@property(nonatomic,getter=isNavigationBarHidden) BOOL navigationBarHidden;

- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated 

加动画的注意:图片严格遵守屏幕宽*44的尺寸,贴图不会波及到状态栏,而且状态栏会自动呈现出最初的样式

2.定制NavigationItem  

NavigationItem是加载在UINavigationBar上的,每个页面单独定制自己的Item。

(1).设置导航条上显示的标题视图,会将视图自动居中显示,在外部设置x,y无效果self.navigationItem.titleViewself.navigationItem.title

(2)UIBarButtonItem

1、通过初始化标题的方法UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"左侧" style:UIBarButtonItemStylePlain target:self action:@selector(leftItemClicked:)];

UIBarButtonItemStylePlain (iOS7中将Item的圆角矩形和边框全部去掉了)

2、用系统提供的样式初始化得到UIBarButtonItem的对象UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(rightItemClicked:)];

3、开发中最常用的创建UIBarButtonItem的方法(这个一定要会)UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithCustomView:customBtn];

(3)显示在导航条的左侧和右侧self.navigationItem.leftBarButtonItem,设置左侧1个视图self.navigationItem.leftBarButtonItems 设置左侧1组视图,数组的元素必须是UIBarButtonItem的对象self.navigationItem.rightBarButtonItem 设置右侧1个视图self.navigationItem.rightBarButtonItems 设置右侧1组视图,数组的元素必须是UIBarButtonItem的对象注意:当我们用leftBarButtonItem覆盖掉系统原本的返回上级界面的按钮,这个时候,UINavigationController的测滑是不能用的。

3.定制ToolBar(工具条)//每个导航控制器,还配备了工具条(44坐标高),默认隐藏【注】toolBar属于NavigationController,一个导航控制器,只有一个

【注】toolBarItems属于每个视图控制器,每个视图控制器单独定制。

(1)拿到导航控制器中工具栏的方法self.navigationController.toolbarHidden=NOself.navigationController.toolbar

(2)设置工具栏的背景图片- (void)setBackgroundImage:(UIImage *)backgroundImage forToolbarPosition:(UIBarPosition)topOrBottom barMetrics:(UIBarMetrics)barMetrics

(3)self.toolbarItems 设置底部,数组中每个元素必需是UIBarButtonItem

注意:开发中,底部工具栏往往自己通过UIView+UIButton定制。

再注意:视图控制器的title属性能同时为navigationItem.title和tabBarItem.title赋值

二.视图控制器间传值(面试题)

【及时性】ΔΔ代理传值、Block传值、Δ通知传值(以后说)

【非及时性】全局变量传值 (只能是基础数据类型)、单例传值(传递对象数据)、文件传值(最慢)、存数据库。

例子:1、我们会把用户信息放到单例里面,当我们需要用户的信息的时候,直接从单例里面取。

三.NSUserDefaults的使用(沙盒保存基本数据的方法)

1、介绍:单例,每个应用程序有且只有一个NSUserDefaults对象,本质是应用程序特定路径下的一个plist文件

2、用途:用于实现数据持久化存储,存储数据量相对较小的数据(比如:用户名,密码。或者程序的一些设置信息等)

3、只能存储基本数据类型:(NSString,NSArray,NSDictionary,NSData,NSDate,bool,NSURL,NSNumber),NSArray,NSDictionary 中的元素也必须是基本数据类型(比如 :NSArray中是字符串,能够写入到UserDefaults,NSArray中是视图控制器对象,则此array不能写入)

4、用法 :

(1)NSUserDefaults *defaluts = [NSUserDefaults standardUserDefaults];//拿到单例      

(2)- (void)setObject:(id)value forKey:(NSString *)defaultName;//向NSUserDefaults,写入数据(内存) 

(3)- (void)removeObjectForKey:(NSString *)defaultName;//删除NSUserDefaults中的对应数据  

(4)- (id)objectForKey:(NSString *)defaultName;//从UserDefaults中读取数据,如果从来没写入过数据,读到的为空      

(5)[defaluts synchronize];//将数据同步给应用程序(执行真正写入plist的操作)

注意:第二个方法和第三个方法执行完之后,一定要执行第5个方法


UITabBarController 分栏控制器/标签栏控制器

【注】标签栏控制器,是UIKit框架提供的一个容器视图控制器,用于切换相同级别的兄弟视图控制器。iOS允许将导航控制器添加到标签栏控制器中进行管理(事实上这种结构非常常见),但原则上,不推荐将分栏控制器添加到导航控制器中进行管理,导航栏控制器放在标签栏控制器里面

一、UITabBarItem简介:UITabBarItem(标签栏项),视图控制器通过tabBarItem属性来定制标签栏项的显示。

1、呈现在标签栏(UITabBar)上方法:

(1).xxx.tabBarItem.image  设置标签栏项的图片;

(2).xxx.tabBarItem.selectedImage 设置标签栏项的选中图片;

(3).xxx.tabBarItem.title  设置标签栏项的title5)xxx.tabBarItem.badgeValue  设置标签栏项的徽标,用于提示用户

(4).xxx.tabBarItem.titlePositionAdjustment设置标题偏移量  正为下为右 负是上是左创建

2、UITabBarItem的方法

(1).[[UITabBarItem alloc] initWithTitle:title image:image1 tag:100];

(2).[[UITabBarItem alloc]initWithTitle:title image:image selectedImage:selectImage];根据title、image、selectedImage创建UITabBarItem

(3).[[UITabBarItem alloc] initWithTabBarSystemItem:xxx tag:0]    根据系统样式去创建UITabBarItem

二、UITabBarController的方法

(1).UITabBarController *tabController = [[UITabBarController alloc] init] 创建一个标签栏控制器

(2).tabController.viewControllers = controllers;

1、viewControllers 数组,数组中的元素必须是视图控制器的对象

2、视图控制器对象的显示顺序(左到右)与在数组中的顺序一致

3、各个视图控制器是并列的关系,彼此互相独立,点击不同tabBarItem,切换不同的视图控制器的视图

4、当viewControllers中视图控制器的对象多于5个的时候,会自动创建一个标题为more的标签栏项,对应的为moreNavigationController的导航控制器的对象,第5个以及5以后的视图控制器会通过列表的形式呈现在moreNavigationController中

5、tabController.moreNavigationController 获取到我们的moreNavigationController

6、tabController.selectedIndex通过下标的方式指定被选中的视图控制器

7、tabController.selectedViewController通过指定被选中的视图控制器的方式

三、协议方法 UITabBarControllerDelegate

1、- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewControllertabBar将要切换到某个子视图控制器,返回YES允许,返回NO不许,第二个参数是被选的视图控制器

2、- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewControllertabBar已经切换到某个子视图控制器,第二个参数是被选的视图控制器

3、- (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray *)viewControllers当more中,将要编辑视图控制器顺序

4、- (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed当more中,将要结束编辑视图控制器顺序

5、- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed当more中,已经结束编辑视图控制器顺序重要

四.自制TabViewController

自制TabViewController第一步NSMutableArray *controllers=[[NSMutableArray alloc]init];//通过数组的形式来创建视图,并且 运用Class class=NSClassFromString([NSString stringWithFormat:@“xxxx”,xxx]);来找数组中的对象,然后初始化视图控件UIViewController *vc=[[class alloc]init];然后把数组中的视图对象赋值给vc,然后把vc添加到开始自己初始化的可变数组中去NSMutableArray *controllers=[[NSMutableArray alloc]init];    NSArray *nameArray=@[@"界面一",@"界面二",@"界面三",@"界面四",@"界面五”];如果视图控件不需要标题,这个数组可以不需要,把相关的去掉就可以了 。    for (NSInteger i=0; i=0) {        UIButton *btn=(UIButton *)[self.view viewWithTag:100+index];        [self btnClick:btn];    }else{        //我们认为这个数据不合理,就把值改为0,改成默认的第一个        [defaults setObject:@"0" forKey:@"index"];        [defaults synchronize];    }这个是存,一般是在button的点击方法中NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];    [defaults setObject:[NSString stringWithFormat:@"%ld",btn.tag-100] forKey:@"index"];    [defaults synchronize];

补充:1、 button.titleEdgeInsets = UIEdgeInsetsMake(30, -25, 0, 0);设置button文字偏移,让开图片,四个值是相对于之前文字的上左下右的距离2、button.imageEdgeInsets = UIEdgeInsetsMake(5, 12, 15, 12);设置图片偏移,让开文字3、button.adjustsImageWhenHighlighted = NO;设置点击不闪烁4、viewWithTag这个方法是深度遍历,也就是说,不仅能找到self.view的子视图,也能找到子视图的子视图 。什么是单例?对于app来说有很多界面,这些功能来说都是同一个人来做的,需要获取用户信息是一个人打开的,主要用来传值点赞是代理写的,视图之间的传值。


其他控件与手势

【其他控件】

1、UISlider 滑块控件介绍:继承自UIControl,为事件驱动型控件,高度固定23,frame设置高度无效果方法:

1)@property(nonatomic) CGRect frame;设置滑块的尺寸

2)@property(nonatomic) float maximumValue设置滑块的最大值,默认值(0.0  1.0)

3)@property(nonatomic) float minimumValue设置滑块的最小值

4)@property(nonatomic) float value设置滑块最初显示的数值,滑动滑块,伴随的value值的改变

5)@property(nonatomic,getter=isContinuous) BOOL continuous控制滑块的值是否时时变化,默认为YES

6)- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents给滑块添加方法

7)UIControlEventValueChanged 当控件的值发生变化时所对应的事件

2、UISegmentedControl 分段选取器介绍:事件驱动型控件,分段选取器会根据文字内容给一个合适的size

1)- (id)initWithItems:(NSArray *)items;初始化传递进去的NSArray里面放置字符串或图片

2)@property(nonatomic) CGRect frame;不要忘记设置frame

3)@property(nonatomic) NSInteger selectedSegmentIndex;设置哪个分段处于选中状态,不设置此属性,任何分段都处于非选中状态

4)- (void)insertSegmentWithTitle:(NSString *)title atIndex:(NSUInteger)segment animated:(BOOL)animated向分段选取器指定的位置插入标题

5)- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents给分段选取器添加方法

6)- (NSString *)titleForSegmentAtIndex:(NSUInteger)segment根据分段的下标,拿到分段的标题

3、UIStepper 步进器介绍:固定的size (94*27), 事件驱动型控件

1)@property(nonatomic) double maximumValue设置最大值

2)@property(nonatomic) double minimumValue设置最小值

3)@property(nonatomic) double stepValue设置步长 (默认值为1 必须>0)(+一次增加的值/-一次减少的值)

4)@property(nonatomic,getter=isContinuous) BOOL continuous设置长按是否连续响应事件

5)- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents给步进器添加方法

4、UIProgressView 进度条介绍:进度条,普通视图控件,高度固定9

1)@property(nonatomic) float progress进度条的进度属性(默认为0,0.0-1.0),值大于1,进度条一直处于满格状态

5、UISwitch 开关介绍:开关控件,事件驱动型控件,固定size(79*27),frame更改size无效

1)、@property(nonatomic,getter=isOn) BOOL on控制开关的开闭(YES 开)

2)、- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents添加事件

6、UIActivityIndicatorView 加载等待提示控件介绍:加载等待提示控件,控件的size固定

1)、- (id)initWithActivityIndicatorStyle:(UIActivityIndicatorViewStyle)style初始化的时候,设定风格样式

2)、@property(nonatomic) CGPoint center一般设置中心点为view的中心点

3)、- (void)startAnimating;让提示控件转动4)- (void)stopAnimating;让提示控件停止转动

7、UIAlertView 介绍:(视图控件-警告框)

1)- (id)initWithTitle:(NSString *)title              message:(NSString *)message            delegate:(id)delegate    cancelButtonTitle:(NSString*)cancelButtonTitle    otherButtonTitles:(NSString*)otherButtonTitles, ...初始化举例:UIAlertView *alert  = [[UIAlertView alloc]initWithTitle:@“xxx”                  message:@"xxx"                  delegate:self        cancelButtonTitle:@"0"  otherButtonTitles:@"1",@"2",nil];

2)- (void)show;显示警告框,同时将alert托管给应用程序

3)- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex  当点击警告框上的按钮时,触发此方法,buttonIndex 按钮在警告框上的位置

8、UIActionSheet 介绍:动作表单

1)- (instancetype)initWithTitle:(NSString*)title delegate:(id)delegate cancelButtonTitle:(NSString*)cancelButtonTitle destructiveButtonTitle:(NSString*)destructiveButtonTitle otherButtonTitles:(NSString*)otherButtonTitles, ...初始化举例:UIActionSheet *atSheet=[[UIActionSheet alloc]            initWithTitle:@“xxxx”                delegate:self cancelButtonTitle:@"x"    destructiveButtonTitle:nil        otherButtonTitles:@"0",@"1",@"...",@"x-1",nil];

2)- (void)showInView:(UIView *)view;;在view上显示动作表单

3)- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex  当点击动作表单上的按钮时,触发此方法,buttonIndex 按钮在动作表单上的位置上面两种方法放在一起用 如下-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

【手势】

一.触摸类UITouch通过触摸类,我们可以实现各式的自定义手势

二.手势类 UIGestureRecognizer介绍:UIGestureRecognizer 所有手势的父类

1)@property(nonatomic,readonly) UIView *view;获取到被添加手势的视图

2)- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;设置某某手势在otherGestureRecognizer手势之后响应 双击优先响应 也是other

3)@property(nonatomic,assign)iddelegate;设置代理UIView的一个常用方法-(void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer用这个方法给UIView及子类添加手势

1、UITapGestureRecognizer 点击手势

1)- (id)initWithTarget:(id)target action:(SEL)action当满足这个手势之后,让谁去调用这个方法

2)@property(nonatomic)NSUInteger numberOfTapsRequired;设置点击次数

3)@property(nonatomic)NSUInteger numberOfTouchesRequired;设置需要多少个手指点击

2、UILongPressGestureRecognizer 长按手势

1)- (id)initWithTarget:(id)target action:(SEL)action当满足这个手势之后,让谁去调用这个方法

2)@property (nonatomic)NSUInteger numberOfTouchesRequired设置几根手指生效

3)@property (nonatomic) CFTimeInterval minimumPressDuration;设置最小长按时间

3、UIPanGestureRecognizer 移动手势

1)- (id)initWithTarget:(id)target action:(SEL)action当满足这个手势之后,让谁去调用这个方法

2)@property (nonatomic)NSUInteger minimumNumberOfTouches;设置最小手指数

3)@property (nonatomic)NSUInteger maximumNumberOfTouches;设置最大手指数

4)- (CGPoint)translationInView:(UIView *)view;相对于View,拖动时偏移的坐标

4、UISwipeGestureRecognizer 清扫手势

1)- (id)initWithTarget:(id)target action:(SEL)action当满足这个手势之后,让谁去调用这个方法

2)@property(nonatomic) UISwipeGestureRecognizerDirection direction设置这个滑动手势要监听哪个方向,即监听滑向哪边,一个手势,只监听一种方向

3)@property(nonatomic)NSUInteger numberOfTouchesRequired;设置需要几根手指滑动

5、UIPinchGestureRecognizer 缩放手势

1)- (id)initWithTarget:(id)target action:(SEL)action当满足这个手势之后,让谁去调用这个方法

2)@property (nonatomic)CGFloat scale;缩放比例

6、UIRotationGestureRecognizer 旋转手势

1)- (id)initWithTarget:(id)target action:(SEL)action当满足这个手势之后,让谁去调用这个方法

2)@property (nonatomic)CGFloat rotation;旋转的角度

三.手势的四种常用状态state

刚开始生效UIGestureRecognizerStateBegan,

每次移动UIGestureRecognizerStateChanged,

手势结束UIGestureRecognizerStateEnded, 

手势被取消UIGestureRecognizerStateCancelled,

四、手势的代理方法

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer//返回值表示能否两个手势混搭补充:从给定的大图中切出指定矩形区域的小图CGImageRef imageRef = CGImageCreateWithImageInRect(image1.CGImage, rect);UIImage *image = [UIImage imageWithCGImage:imageRef];


UIScrollView/滚动视图

【注】滚动视图(UIScrollView)和表格视图(UITableView)是UI知识体系中,最重要的两个控件。滚动视图本身不显示,或者只显示一个背景,主要负责子视图的滚动和翻页。是一个没有文字的TextView。多用于图片的显示,或者布局的更改(如,弹出键盘时,可以使用滚动视图,来操作布局向上滚动)

【注】UIScrollView常用有四个子类,UITextView,UITableView,UICollectionView,UIWebView

 前言:

1)导航控制器结合UIScrollView使用,需要将此属性设置为NO,来消除对UIScrollView的影响self.automaticallyAdjustsScrollViewInsets = NO;

2)添加到scrollView上的视图可以叫内容视图[scrollView addSubview:imageView];

一.基本属性方法

1)@property(nonatomic)CGSize contentSize;  设置内容视图的滚动区域,contentSize一般设置成内容视图的大小,或者是多个内容视图的size和 contentSize 比scrollView本身的size大时,scrollView才有滚动效果

2)@property(nonatomic) BOOL                        showsHorizontalScrollIndicator  横向滚动条是否显示,默认是YES

3)@property(nonatomic) BOOL showsVerticalScrollIndicator  纵向滚动条是否显示,默认是YES

4)@property(nonatomic)BOOL bounces  是否有边界回弹效果

5)@property(nonatomic)CGPoint contentOffset  内容视图左上角的点为坐标原点,scrollView的起始点与内容视图左上角的点(内容视图的起始点)的偏移量

6)@property(nonatomic,getter=isPagingEnabled) BOOL pagingEnabled  设置scrollView的分页属性,会将内容视图进行分页计算,每页大小与scrollView的size一致

7)@property(nonatomic) CGFloat maximumZoomScale  设置内容视图的最大缩放系数

8)@property(nonatomic) CGFloat minimumZoomScale    设置内容视图的最小缩放系数

注意:7)和8)两条属性需要和- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{}结合使用。

二.协议方法

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{//    NSLog(@"已经滑动的时候调用这个方法!contofset一直在变:(%f:%f)",scrollView.contentOffset.x,scrollView.contentOffset.y);}//在滚动的时候调用这个方法,而且是时时调用

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{    NSLog(@"刚开始拖拽的时候调用这个方法!");}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{    NSLog(@"结束拖拽的时候调用");}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{    NSLog(@"将要结束拖拽的时候调用这个方法,第一个参数是scrollView,第二个参数是加速度,第三个参数是预定停留点");}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{    NSLog(@"将要开始减速的时候,调用这个方法");}//一定得有减速的过程,将要减速的时候,调用

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{    NSLog(@"结束减速过程之后,调用的方法");}//已经结束滑动的时候调用

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{    NSLog(@"已经结束滑动的时候调用");}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{    return [scrollView.subviews objectAtIndex:0];}//这个方法很重要,而且当我们设置属性pagingEnabled=YES,就一定会调用这个方法

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view{    NSLog(@"将要缩放的时候,调用的方法");}//返回缩放的视图

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{    NSLog(@"结束缩放的时候,调用的方法。第一参数是ScrollView,第二个参数是被缩放的视图,第三个参数是缩放的比例");}

- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView{    NSLog(@"我要上去了");    return YES;}//点击状态栏的时候调用,当返回YES的时候,就是让scrollView回到顶部,当返回NO的时候,就不能回到顶部

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView{    NSLog(@"我上来了!");}//已经到顶部的时候,调用这个方法

三.UIPageControl和广告栏(照片墙)

1)@property(nonatomic) NSInteger numberOfPages;设置总页数

2)@property(nonatomic) NSInteger currentPage;设置当前页,页数从0开始

3)@property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled;userInteractionEnabled 视图的用户交互属性,设置为NO后,视图无法响应用户的交互行为

4)@property(nonatomic,retain) UIColor *currentPageIndicatorTintColor设置当前点的颜色

5)@property(nonatomic,retain) UIColor *pageIndicatorTintColor设置其它点的颜色


UITableView/表格视图

【知识点】【TableView使用】【TableView定制】【Cell定制】

1.UITableView的结构

【注】UITableView派生自UIScrollView

【注】UITableView的结构如下背景是滚动视图每个横向的表格称为Cell(UITableViewCell)<注>每个cell既可以存储数据,也可以接受选中的事件,我们可以选中某个cell时,下拉列表,也可以选中某个cell时,推出新的页面。在编辑模式下还可以选中多个cell,批量删除等。

<注>通过自定义cell,更可以在cell上添加任何需要的视图。多个cell可以进行分组管理

【注】UITableView的cell复用UITableView只会添加所需的一定数量的cell,仅仅比同屏显示的cell多一点,当tableView滚动时,重复使用这些cell,刷新内容。

【注】UITableView具有编辑状态和普通状态两种模式。很多属性方法都只在某一种模式下生效

2.UITableView的基本属性和常用方法基本属性:

1)@property (nonatomic) UITableViewCellSeparatorStyle separatorStyle设置分割线的样式

2)@property (nonatomic, retain) UIColor              *separatorColor设置分割线的颜色

3)@property (nonatomic, retain) UIView *tableHeaderView整个tableView的头部

4)@property (nonatomic, retain) UIView *tableFooterView

整个tableView的底部常用方法:

1)- (void)reloadData; 刷新tabView的数据

2)- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation刷新tabView某个section的数据,第二个参数是动画类型

3)- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation删除行 第一个参数是数组,数组里面每个元素是要删除的cell的位置,第二个参数是删除时候的动画

4)- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;删除组 第一个参数是NSIndexSet包装后,组的位置,第二个参数是删除时的动画[NSIndexSet indexSetWithIndex:indexPath.section]

5)- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;  插入行 第一个元素是一个数组,数组里面每个元素都是要插入行的位置;第二个元素是动画效果

6)- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation 插入组

7)- (void)setEditing:(BOOL)editing animated:(BOOL)animated 设置tabView是否处于编辑状态

3.UITableViewCell的基本属性

1)@property (nonatomic, retain)UIView *selectedBackgroundView设置cell选取后的背景视图

2)@property (nonatomic) UITableViewCellSelectionStyle selectionStyle设置cell被选取后的样式3)@property (nonatomic) UITableViewCellAccessoryType    accessoryType设置右边图标的样式UITableViewCellAccessoryDisclosureIndicator 是箭头

4.UITableView的协议

(1)设置Cell

1)- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;  设置每组里面有多少行,大部分的情况都是只有一组

2)-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath设置cell的高度 默认高度44

3)- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath返回cell

(2)section

 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 设置有多少组,默认是1

(3)header    

1、 -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section设置section头部的标题

2、-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section  设置头部section的高度 

3、-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section  当我们头部的样式不满足我们要求的时候,我们需要自己去定义个View

(4)Footer

1、- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section设置section底部的标题

2、-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForFooterInSection:(NSInteger)section  设置section底部的高度 

3、-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section  当我们底部的样式不满足我们要求的时候,我们需要自己去定义个View

(5)选择  

1)- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath    选中tableView中的某一行时,触发此方法  

2)- (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated    通过tableView设置某一行,自动反选,反选的代理方法不再被调用  

3)- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath    某一行被反选时,触发此方法

5.UITableView的cell编辑与移动(1)下面是关于编辑的方法(4个) 仅在编辑模式生效  

1)- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath  返回某一行,return YES允许被编辑, return NO 不能被编辑  

 2)- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath  返回某一行的编辑状态 UITableViewCellEditingStyleInsert  插入 UITableViewCellEditingStyleDelete  删除    

3)- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath  返回删除时右侧按钮的文字    

4)- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath  真正开始编辑,如果是insert,点击+就调用,如果delete,必须点击右侧字体才调用

(2)关于移动cell的方法 仅在编辑模式下生效    

1)- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath    返回某一行可不可以移动    

2)- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath    当移动cell时调用,只有实现了这个方法,才能移动cell

6.UITableViewController

7.设置tabView的索引

1)- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView 返回值为一组索引标题(一组字符串)

2)- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index title 被选中的索引标题  index 索引标题在索引中的位置(在索引标题数组中的下标)  返回值为要指向的分区下标 

8、UISearchDisplayController和UISearchBar

1) UISearchBar 正常创建,然后赋值给tableHeaderView

2) UISearchDisplayController

1、- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController创建搜索控制器,传入一个搜索条,点击搜索条,可以触发搜索vc的搜索模式,搜索模式作用在self上    

2、@property(nonatomic,assign)idsearchResultsDataSource

3、@property(nonatomic,assign)idsearchResultsDelegate

9.cell的定制 

1)-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 重写这个方法,第一参数是样式,第二个参数是标识 

2)- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier;这个方法是用来提前注册cell,可以让在编译器创建cell之前知道创建哪种类型的cell,效率高  第一个参数:cell的class 第二个参数是标识 

3)- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath这个方法根据cell的标识和cell的位置取出cell,一定是和提前注册一起使用,当队列中没有的cell的时候,会自动帮你创建cell注意:提前注册手写cell,一定是上面三个方法都用到

4)UINib *nib=[UINib nibWithNibName:@"BookCell" bundle:nil]根据cell的名字创建UINib

5)[_tableView registerNib:nib forCellReuseIdentifier:@"BookCell"];  提前注册xib写的cell注意:提前注册定制的cell,这两个方法和第3个方法一起用

10.通过XIB进行Cell定制【三大注意事项】

1.必须确保Xib文件关联类是自定义的cell类

2.必须确保Xib文件中只有一个cell

3.必须手动拷贝Cell的唯一ID,否则不能复用

补充:[[UIDevice currentDevice].systemVersion floatValue]获取系统版本号


UICollectionView/表格视图

1.介绍    集合视图,iOS6之后出现的视图控件,与UITableView类似,最大的特点是可以对cell实现灵活的布局 UICollectionView 使用的cell为UICollectionViewCell

注意:self.automaticallyAdjustsScrollViewInsets = NO;

2.UICollectionViewFlowLayout 

介绍:UICollectionViewFlowLayout 系统提供的,能够实现cell的网格布局UICollectionViewFlowLayout的父类是UICollectionViewLayout,UICollectionViewLayout 集合视图的布局类,是一个抽象基类

1)@property (nonatomic) UICollectionViewScrollDirection scrollDirection设置collectionView的方向UICollectionViewScrollDirectionVertical 竖直  UICollectionViewScrollDirectionHorizontal 水平

2)@property (nonatomic) CGFloat  minimumLineSpacing;设置横向的最小间隔

3)@property (nonatomic) CGFloat minimumInteritemSpacing;设置纵向的最小间隔

注意:如果CollectionView垂直滚动,横向的最小间隔能直接生效;纵向的最小间隔由实际间隔需要根据item的size 和edgesInsets的值来调节

3.UICollectionView 基本方法和属性 

1)- (id)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout利用布局对象,实现集合视图的初始化

2)@property (nonatomic, assign) iddelegate设置代理 UICollectionViewDelegateFlowLayout

3)@property (nonatomic, assign) iddataSource;设置代理 UICollectionViewDataSource4.UICollectionView 代理方法cell的方法

4)- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath指定每一个item的大小

5)- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section一个section 有多少个Item(cell)

6)- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath返回Cell

(1)Cell的注册方法

- (void)registerNib:(UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier    

 - (void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier

(2)Cell取出的方式

- (id)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath*)indexPath通过重用标识符和indexPath到UICollectionView的重用队列中获取cell对象,因为已经提前注册了cell,如果获取不到cell对象,UICollectionView会根据注册的cell样式,自动创建cell对象

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPathcell被选中的时候调用的方法section的方法

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView设置组的个数

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section  设置顶部view的高度。如果垂直滚动,view的width与集合视图一致,需要设置高度

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section设置底部view的高度 

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath通过此方法为section的headerView和footerView赋值

(1)注册方法

- (void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;  注册的种类UICollectionElementKindSectionHeader 设置sectionHeaderViewUICollectionElementKindSectionFooter 设置SectionFooterView

(2)取出的方式

- (id)dequeueReusableSupplementaryViewOfKind:(NSString*)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath*)indexPath通过此方法为section的headerView和footerView赋值    用下面方法判断是header还是footer[kind isEqualToString:UICollectionElementKindSectionHeader]cell整体边距

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section描述的是所有cell相对于另一个视图上、左、下、右的距离

补充:[[UIDevice currentDevice].systemVersion floatValue]获取系统版本号


GET请求和数据下载、JSON解析

【知识点】

一. 数据的网络请求

【注】大多数APP都是依托于服务器的,由服务器负责数据的管理交互,分发,筛选等等。APP做的事情就是发送请求,接收数据。当然有些请求也可以伴随数据的上传。

请求(Request):APP客户端发送给服务器的数据,根据服务器协议,通知服务器,要求服务器做出数据的筛选,管理或分发。

响应(Respond):服务器接收到APP的请求,会回馈响应。响应包括TCP稳定链接的建立,以及数据的传输。

【注】网络数据传输的常用协议,有TCP和UDP。(了解)

TCP:首先建立稳定的传输链接,保证传输数据,正确稳定,序列正常,适合传输文件

UDP:不建立链接,发送方发送数据后,对数据不再负责,快速,但是容易造成丢包,序列紊乱和后发先至,适合即时通讯,或者广播消息。举例:淘宝, QQ, 微信,传视频等

【注】数据的请求协议:手机应用开发的绝大多数数据请求协议都是使用http(超文本传输协议)。

主要使用的请求:<1>Post请求:请求数据不裸露,适合向服务器上传文件等大数据。

<2>get请求:最常用的app数据请求模式,通过裸露的传参方式,将我们请求的数据发送给服务端,服务端解析http协议,根据参数管理,筛选,分发数据,并作出相应响应。用于下载数据。

【注】数据格式JSon(很多,很简单)和Xml(很少,很困难)在移动APP当中,服务器发送过来的数据,都是字符串,有两种格式JSon和Xml.将JSon格式的数据提取出来,保存到数据模型中的过程,称为JSon解析.将Xml格式的数据提取出来,保存到数据模型中的过程,称为Xml解析

【注】一般客户端流程,发送请求 -> 等待响应 -> 建立链接 ->下载数据 -> 解析数据 -> 存入数据模型 -> mvc 显示到UI

二.网络数据的下载AFNetworking初步介绍:AFNetWorking2.0是目前最受开发欢迎的第三方网络框架,里面不但封装了最基本的NSURLConnection 而且还封装了iOS7之后的NSURLSession向下兼容到iOS6,arc+block 不用添加任何其他库依赖,json的数据,能自动解析(NSJSONSerialization)

1)AFHTTPRequestOperationManager *manager=[AFHTTPRequestOperationManager manager];拿到数据请求的管理类

2)manager.responseSerializer.acceptableContentTypes=[NSSet setWithObject:@"application/json”];告诉manager,需要解析的数据类型(服务端下发给客户端的数据是什么类型的) 

application/json是json数据  text/xml是xml数据

3)manager.responseSerializer=[AFHTTPResponseSerializer serializer];    将一个新的解析对象 AFHTTPResponseSerializer 赋值过去,数据不会再被自动解析

1、对json数据的Get请求

- (AFHTTPRequestOperation *)GET:(NSString *)URLString                    parameters:(id)parameters                        success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success                        failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;

三. JSON解析[核心和重点]

<1>Json数据的格式{}中表示一个字典[]中表示一个数组key: value 表示一个键值对"string"  表示一个字符串, 表示并列数据

<2> 如何解析

四. SDWebImage异步下载图片知识

补充kvc:

key-value-coding 键值编码,kvc 是oc动态语法结构一种使用形式,主要是用来进行赋值取值操作,所有NSObject类型的对象都支持KVC,点语法是特殊的一种kvc。把value赋值给一个叫name的属性 ,程序内部:查找是否有setName方法,有直接赋值,没有就继续查找_name,有就赋值,没有就查找属性名为name的属性。KVC最常用的方法,可以根据字典中的key对model里面的值赋值。(习惯用法:当使用时保持key和属性的名字一致)例如:

 [_stuModel setValuesForKeysWithDictionary:dic];  

  NSDictionary *dic=@{@"name":@"佐罗",@"sex":@"男",@"friends":@[@"xx.xx",@"xxx.xxx"],@"height":@"186"};    //当没有找到set方法,_属性,属性的时候,它会在model里面找setValue:forUndefinedKey: 如果我们没有重写,程序就会崩溃在model的.m文件中重写-(void)setValue:(id)value forUndefinedKey:(NSString *)key{    //可以不写打印,写了可以提示自己    NSLog(@"UndefinedKey:%@",key);}程序就不会崩溃了 

补充 kvo:    

key-value-observer 键值观察,用来观察使用kvc的对象的属性,常用来观察属性值的变化  

第一参数:设置观察者  

第二个参数:观察哪个属性   

第三个参数:观察的属性的哪种变化  

第四个参数写nil

1、通知中心 每个应用程序有且只有一个通知中心的对象(单例),可以理解为广播站。任何对象都可以通过通知中心发送广播,任何对象都可以通过通知中心注册成为某条广播的观察者(具有接收/收听某条广播能力的对象)

1)添加观察者[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(xxx) name:@“message” object:nil];在通知中心注册self为@“message”广播的观察者,一旦有其他对象发送这条广播,self就能接收到并触发@selector(xxx)方法

2)移除观察者[[NSNotificationCenter defaultCenter] removeObserver:self name:@“message” object:nil];在通知中心移除self对@“message”的观察

3)发送通知[[NSNotificationCenter defaultCenter] postNotificationName:@“message” object:nil userInfo:dic];对象通过通知中心发送消息,dic的消息会被传到观察者中

2、视频  MPMoviePlayerViewController介绍:

MPMoviePlayerViewController是视频播放器的控制器(能够播放mp4、avi、mov格式的视频,支持本地和远程视频的播放)

1)#import此framework中带有视频播放器

2) 创建的方法_playController=[[MPMoviePlayerViewController alloc]initWithContentURL:url];

3) 设置资源类型_playController.moviePlayer.movieSourceType视频资源分为普通的文件资源,还有流媒体格式(.m3u8)的视频资源,moviePlayer属性为视频播放器,指定播放的资源的类型

4) 要用模态化的方式呈现

5)[_playController.moviePlayer play];

注意:在用的时候,通过点击done按钮后,销毁_playController步骤:

1)[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playBack) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];在通知中心注册self为MPMoviePlayerPlaybackDidFinishNotification广播的观察者,一旦有其他对象发送这条广播,self就能接收到并触发playBack方法点击done按钮->视频播放器会自动通过通知中心发送MPMoviePlayerPlaybackDidFinishNotification这条广播

2)实现playBack方法[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];在通知中心移除self对MPMoviePlayerPlaybackDidFinishNotification广播的观察(不要忘记)  //停掉播放器  [_playController.moviePlayer stop];  //销毁playController  _playController = nil;

3、音频  AVAudioPlayer介绍:

AVAudioPlayer是音频播放器

1)#import带有音频播放器的framework

2) _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];本地的资源路径生成url用fileURLWithPath

3)_audioPlayer.delegate设置代理

4)[_audioPlayer prepareToPlay];对音频资源进行预加载

5)[_audioPlayer play];播放音频

6)[_audioPlayer stop];停止播放音频

代理方法

1)- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;当成功播放完成一首歌后,调用此方法

4、相机和相册  UIImagePickerController介绍:UIImagePickerController用来获取拍照和相册库资源

1)UIImagePickerController *picker = [[UIImagePickerController alloc] init];创建

2)@property(nonatomic)          UIImagePickerControllerSourceType    sourceType;通过UIImagePickerController 来获取拍照和相册库资源UIImagePickerControllerSourceTypePhotoLibrary,相册UIImagePickerControllerSourceTypeCamera,  相机UIImagePickerControllerSourceTypeSavedPhotosAlbum  图册

3)@property(nonatomic,assign)    iddelegate

4)@property(nonatomic)BOOL allowsEditing    是否允许对图片、视频资源进行后续处理  

5)通过模态化的方式呈现到程序中代理方法

1)+ (BOOL)isSourceTypeAvailable:(UIImagePickerControllerSourceType)sourceType;用来判断是否可以调用相机或者相册,sourceType是下面的UIImagePickerControllerSourceType

2)- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;点击picker上的cancel按钮时,触发的方法,里面picker需要dismiss

3)- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info点击choose按钮触发的方法,info 带有选中资源的信息

1、NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];判断选中的资源的类型[mediaType isEqualToString:(NSString *)kUTTypeImage]注意需要#import//此framework中带有系统预置的多媒体常量参数

2、UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];通过字典获取选中的图片APP之间的跳转所用的函数在第一界面鞋写在需要跳转的或者btn点击下  [[UIApplication sharedApplication] openURL:[NSURL URLWithString:encodeString]];并且在targets中info 找到 URLtypes  做一个标记 跳转传值的话需要用到函数app一个代理方法- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{    ((ViewController*)self.window.rootViewController).label.text=string;}有时搜索框不能搜索中文 我们需要把中文转化成 万国码方法如下将字符串的中文转码NSString * string=@"yxl://你好";    NSString * encodeString=[string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //将转码后的字符串转回来    NSString * string=[url.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

地图一、iOS系统自带定位,用CLLocationManager就可以轻松的实现定位的操作,获得的是一组经纬度。

1、导入CoreLocation.framework框架

2、定义属性  CLLocationManager *_locationManager

3、@property(assign, nonatomic) iddelegate;

4、@property(assign, nonatomic) CLLocationDistance distanceFilter;

设置过滤器的距离

5、@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;

设置精确度,位置服务大量消耗电池电量,下面罗列优先级别从上而下:

6、ios8.0之后请求授权,需要在plist文件中添加字段

NSLocationWhenInUseUsageDescription  值为YES请求定位的用户授权

requestWhenInUseAuthorization 只有应用在使用的时候允许授权

requestAlwaysAuthorization    在任何时候都需要授权,如果要在后台定位,需要有一个明确的提示,告诉用户,你的应用会在后台定位,电池会加快消耗

[_locationManager requestWhenInUseAuthorization];

7、- (void)startUpdatingLocation;

开启位置服务

8、-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;

当位置发生变化时调用这个方法

9 、-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error

当定位失败的时候调用这个方法

CLLocation的属性CLLocationCoordinate2D中包含了经度longitude 纬度latitude

二、根据上面得到的经纬度可以获取相应的身份、城市、街道等信息。

1、CLGeocoder *geocoder=[[CLGeocoder alloc]init];

CLGeocoder类中有几个方法,一个是把经纬度转化成大家能看懂的信息,比如:city,county,街道等等

2、- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;

根据经纬度反向地理编译出地址信息

CLPlacemark有很多属性,thoroughfare获取街道,locality获取城市,administrativeArea,获取省(直辖市).......

测试地址:经度:121.487237,纬度:31.380998

多线程

1、进程和线程

1)、什么是进程

进程是指在系统中正在运行的一个应用程序,每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内。

2)、什么是线程

1个进程要想执行任务,必需得有线程(每1个进程至少要有1条线程);线程是进程的基本单元,一个进程(程序)的所有任务都在线程中执行。

比如使用酷狗播放音乐、使用迅雷下载电影,都需要在线程中执行

3)、线程的串行

1个线程中任务的执行是串行的。如果要在这个线程中执行多个任务,那么智能一个一个地按顺序执行这些任务,也就是说,在同一时间内,一个线程只能执行一个任务

2、多线程

1)、什么是多线程

1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务

2)、多线程的原理

同一时间,CPU只能处理1条线程,只有1条线程在工作(执行)。多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)。CPU调度线程的速度足够快,就造成了多线程并发执行的假像。

3、多线程的优缺点

优点:1、能适当提高程序的执行效率

2、能适当提高资源利用率(CPU、内存利用率)

缺点:1、开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能。

2、线程越多,CPU在调度线程上的开销就越大(如果有N条多线程,cpu会在N多线程之间调度,CPU会累死,消耗大量的CPU资源,每条线程被调度执行的频次会降低,线程的执行效率就下降了)

3、程序设计更加复杂:比如线程之间的通信,多线程的数据共享

4、多线程在iOS开发中的应用

主线程:一个iOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”

主线程的主要作用:显示\刷新UI界面、处理UI事件

主线程的使用注意:别将比较耗时的操作放在主线程中。耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验(见代码事例:BlockingMainThread)

5、线程的实现

iOS中实现线程的可行方式有:

pthread 底层的C线程库(不考虑)

NSThread Objective-C的线程类

NSOperationQueue 线程池/线程队列

GCD 使用Block语法的线程池/线程队列

6、NSThread Objective-C的线程类

1)、创建线程,并自动执行

[NSThread detachNewThreadSelector:@selector(doSomeThing) toTarget:self withObject:nil];

2)、创建线程,不自动执行

[[NSThread alloc] initWithTarget:self selector:@selector(doSomeThing) object:nil];

3)、设置线程名

thread.name = @"另一个线程";

4)、执行线程

[thread start];

5)、函数内获取当前线程

[NSThread currentThread];

6)、获取主线程

[NSThread mainThread];

7)、线程休眠

[NSThread sleepForTimeInterval:1.0f];  // 休眠几秒

[NSThread sleepUntilDate:date]; // 休眠到指定时间

8)、线程退出

[NSThread exit];

9)、线程通信

[self performSelector:@selector(function) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];

7、NSOperationQueue 线程池/线程队列(内部实现是GCD)

1)、NSInvocationOperation

1、创建操作对象,封装要执行的任务

NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];

2、执行操作

[operation start];

2)、NSBlockOperation子类

1、创建NSBlockOperation操作对象

NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{

}];

2、添加操作

[operation addExecutionBlock:^{

}];

3、开启执行操作

[operation start];

3)、NSOperationQueue

添加操作到NSOperationQueue中,自动执行操作,自动开启线程 1、创建NSOperationQueue

[[NSOperationQueue alloc] init];

2、设置最大并发数

queue.maxConcurrentOperationCount = 1;

3、添加任务到队列里

[queue addOperation:blockOperation];

4、让队列里面,所有的Operation都取消

[queue cancelAllOperations];

5、获取当前线程对列

[NSOperationQueue currentQueue]

6、获取主线程对列

[NSOperationQueue mainQueue]

7、添加任务间的依赖关系,前者依赖于后者的完成,也就是后者执行完,前者才能执行,依赖关系需要放在添加到队列之前设置

[invocation addDependency:blockOperation];

8、GCD 使用Block语法的线程池/线程队列

介绍:全称是Grand Central Dispatch,纯C语言,提供了非常多强大的函数

优势:1、GCD是苹果公司为多核的并行运算提出的解决方案

2、GCD会自动利用更多的CPU内核(比如双核、四核)

3、GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程),程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

术语补充:

1、同步和异步决定了要不要开启新的线程

同步:在当前线程中执行任务,不具备开启新线程的能力

异步:在新的线程中执行任务,具备开启新线程的能力

2、并发和串行决定了任务的执行方式

并发:多个任务并发(同时)执行

串行:一个任务执行完毕后,再执行下一个任务

获得串行队列:

1、使用dispatch_queue_create函数创建串行队列

dispatch_queue_t queue=dispatch_queue_create("sjl", NULL);

第一个参数队列名称,第二个参数用NUKLL即可

2、使用主队列(跟主线程相关的队列)

主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行

获得并发队列:

1、GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建

dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

第一个参数,是全局并发队列的优先级

#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高

#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中)

#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低

#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台添加同步任务

第二个参数,写0即可

用同步的方式执行任务 dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

参数说明:

queue:队列

block:任务

用异步的方式执行任务 dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

9、线程锁

- (NSString *)md5:(NSString *)str

{

const char *cStr = [str UTF8String];

unsigned char result[16];

CC_MD5(cStr, (CC_LONG)strlen(cStr), result); // This is the md5 call

return [NSString stringWithFormat:

@"XXXXXXXXXXXXXXXX",    // 小写 x 表示输出的是小写 MD5 ,大写 X 表示输出的是大写 MD5

result[0], result[1], result[2], result[3],

result[4], result[5], result[6], result[7],

result[8], result[9], result[10], result[11],

result[12], result[13], result[14], result[15]

];

}

iOS技术分享
Web note ad 1