oc部分筆記

1.自定義控件

a.繼承某個(gè)控件

b.重寫(xiě)initWithFrame方法可以設(shè)置一些它的屬性

c.在layoutsubviews添加子控件的重寫(xiě)frame

d.提供一個(gè)屬性重寫(xiě)它的set方法

修飾符

用strong修飾OC對(duì)象以及NSString和Block ,沒(méi)添加到父控件上的控件

用weak修飾已經(jīng)被添加到父控件上的控件以及代理對(duì)象

用assign基本數(shù)據(jù)類(lèi)型披蕉、枚舉萎馅、結(jié)構(gòu)體(非OC對(duì)象)class類(lèi)型

用copy修飾一種情況下的NSString-->不確定賦值過(guò)程中用的是可變還是不可變字符串

2.簡(jiǎn)單的MVC

a.就是model模型vIewcontroll控制器view視圖.

3.xib的創(chuàng)建和story的創(chuàng)建

加載xib的方式有

[nsbundlemainnbundle ]loadNibName:"文件名"options :nil];

4.通過(guò)純代碼創(chuàng)建的初始化一定會(huì)調(diào)用initWithFrame方法

通過(guò)xib的創(chuàng)建和story的創(chuàng)建的一定會(huì)調(diào)用aweakFromNib方法.

通過(guò)xib的創(chuàng)建對(duì)于它加載視圖的時(shí)候會(huì)調(diào)用initWithCoder方法.

(1)awakeFromNib和initWithCoder:差別

awakeFromNib是初始化完畢調(diào)用并且從xib或者storyboard加載完畢就會(huì)調(diào)用

initWithCoder:只要對(duì)象是從文件解析來(lái)的扎阶,就會(huì)調(diào)用是初始化的時(shí)候調(diào)用

同時(shí)存在會(huì)先調(diào)用initWithCoder:

(2)initWithCoder: & initWithFrame:

initWithCoder:使用文件加載的對(duì)象調(diào)用(如從xib或stroyboard中創(chuàng)建)

initWithFrame:使用代碼加載的對(duì)象調(diào)用(使用純代碼創(chuàng)建)

注意:所以為了同時(shí)兼顧從文件和從代碼解析的對(duì)象初始化众旗,要同時(shí)在initWithCoder:和initWithFrame:中進(jìn)行初始化

5.拳皇設(shè)計(jì)的imageView的動(dòng)畫(huà)搖動(dòng)bottomLeft出來(lái)mode

kvc和Kvo的區(qū)別:

kvc可以快速的字典轉(zhuǎn)模型給私有的變量賦值給屬性賦值也行

// KVO :鍵值監(jiān)聽(tīng)

//作用:可以監(jiān)聽(tīng)某個(gè)對(duì)象屬性值的改變

/**

*給p對(duì)象添加一個(gè)監(jiān)聽(tīng)器

*

*Observer:監(jiān)聽(tīng)器(觀察者)

*KeyPath :監(jiān)聽(tīng)哪一個(gè)屬性值的改變

*/

[p addObserver:selfforKeyPath:@"name"options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:@"asd"];

6.

在-(void)viewDidLoad里面調(diào)用

// self-sizing技術(shù)(iOS8開(kāi)始支持的)

//告訴tableView所有cell的真實(shí)高度是自動(dòng)計(jì)算的(根據(jù)你設(shè)置的約束計(jì)算)

self.tableView.rowHeight = UITableViewAutomaticDimension;

//告訴所有cell的估算高度

self.tableView.estimatedRowHeight =44;

if(status.isVip) {//是vip

self.vipImageView.hidden =NO;

self.nameLabel.textColor = [UIColor orangeColor];

}else{//不是vip

self.vipImageView.hidden =YES;

self.nameLabel.textColor = [UIColor blackColor];

}

if(status.picture) {//有配圖

self.pictureImageView.hidden =NO;

self.pictureImageView.image = [UIImage imageNamed:status.picture];

self.pictureHeight.constant =100;

self.pictureBottom.constant =10;

}else{//沒(méi)有配圖

self.pictureImageView.hidden =YES;

self.pictureHeight.constant =0;

self.pictureBottom.constant =0;

}

6.靜態(tài)cell:

當(dāng)界面處于不改變的狀態(tài)就是用靜態(tài)cell

在做一些“死”頁(yè)面的時(shí)候SB的靜態(tài)cell是很好的選擇,靜態(tài)cell也不是什么都不能做,靜態(tài)cell里的button還是可以拖到@implementation中形成IBAction的,但是是無(wú)法生成IBOutlet屬性或字段的。

即使你強(qiáng)行的給一個(gè)靜態(tài)的cell指定了一個(gè)cell的類(lèi)孝情,也是無(wú)法向其內(nèi)部拖入IBOutlet的。這就是靜態(tài)cell的局限性洒嗤,但是如果你要設(shè)置的數(shù)據(jù)不多還是可以考慮用靜態(tài)cell箫荡,因?yàn)槟憧梢酝ㄟ^(guò)給cell上的控件設(shè)tag來(lái)找到它從而賦值。

7.問(wèn)題1:簡(jiǎn)述registerNib:(nullableUINib *)nib forCellReuseIdentifier:(NSString *)identifier和registerClass:(nullableClass)cellClass forCellReuseIdentifier:(NSString *)identifier這2個(gè)方法的區(qū)別?

答:registerClass這個(gè)方法是根據(jù)ID注冊(cè)對(duì)應(yīng)的cell類(lèi)型,系統(tǒng)創(chuàng)建cell的方式是通過(guò)alloc/initWithStyle...

registerNib這個(gè)方法是根據(jù)ID注冊(cè)一個(gè)xib文件,系統(tǒng)創(chuàng)建cell的方式是通過(guò)加載xib文件.

問(wèn)題2:如何計(jì)算一段文字的寬度和高度?

答:第一種情況:如果label只有一行,通過(guò)sizeWithAttributes:這個(gè)方法,告知這段文字的字體和字體大小就可以計(jì)算這段文件的尺寸.

第二種情況:如果label需要換行計(jì)算高度,通過(guò)boundingRectWithSize: options: attributes:attributes context:這個(gè)方法,告知這段文字的字體和字體大小,并且在一個(gè)限制的尺寸內(nèi)計(jì)算這段文字的尺寸.

8.xib和storyBoard的創(chuàng)建:

1.xib創(chuàng)建的控制器首先要讓這個(gè)控制器擁有一個(gè)View就是連線到View

2.直接加載[self.view addSubview:[[[NSBundle mainBundle]loadNibNamed:@"One"owner:selfoptions:nil]lastObject]];

storyboard創(chuàng)建的要給storyboard綁定標(biāo)識(shí)其次在加載storyboardde視圖

例如:

UIStoryboard *story =[UIStoryboard storyboardWithName:@"OYVC"bundle:nil];//qwer為標(biāo)識(shí)符

[self.viewaddSubview:[story instantiateViewControllerWithIdentifier:@"qwer"].view];

9:為什么在遍歷一個(gè)數(shù)組的時(shí)候,不能一邊遍歷一邊刪除,這樣可能會(huì)導(dǎo)致什么問(wèn)題?

因?yàn)樵賱h除的同時(shí)遍歷的下標(biāo)將會(huì)隨著改變這樣就會(huì)導(dǎo)致數(shù)組遍歷混亂.

10.通知

//創(chuàng)建通知

1.NSNotification *note = [NSNotification notificationWithName:@"軍事新聞"object:comp1 userInfo:@{@"title":@"XXIIXIXIIXIXI"}];

//發(fā)布通知

2.[[NSNotificationCenter defaultCenter] postNotification:note];

1+2=[[NSNotificationCenter defaultCenter] postNotificationName:@"軍事新聞"object:comp1 userInfo:@{@"title":@"XXIIXIXIIXIXIUIUIUIUIUIUIUIUI"}];

[[NSNotificationCenter defaultCenter] postNotificationName:@"娛樂(lè)新聞"object:comp2 userInfo:@{@"title":@"XXIIXIXIIXIXIUIUIUIUIUIUIUIUI"}];

//匿名通知

[[NSNotificationCenter defaultCenter] postNotificationName:@"娛樂(lè)新聞"object:niluserInfo:@{@"title":@"XXIIXIXIIXIXIUIUIUIUIUIUIUIUI"}];

//接收通知

[[NSNotificationCenter defaultCenter] addObserver:p1 selector:@selector(getNews:) name:@"軍事新聞"object:comp1];

[[NSNotificationCenter defaultCenter] addObserver:p2 selector:@selector(getNews:) name:@"娛樂(lè)新聞"object:nil];

// [[NSNotificationCenter defaultCenter] addObserver:p2 selector:@selector(getNews:) name:@"娛樂(lè)新聞" object:nil];

addObserver是接收通知者selector:@selector(getNews:)是通知要執(zhí)行的方法name:@"軍事新聞"是通知消息的名字object是參數(shù)

11.通知的使用

a.注冊(cè)通知:[[NSNotificationCenter defaultCenter]postNotificationName:@"data"object:vc userInfo:@{@"mimi":self.textF.text}];

postNotificationName:消息的標(biāo)識(shí)假如是nil的話相當(dāng)于誰(shuí)都可以接收消息object:是將要接收消息者是發(fā)出者userInfo:是你要傳遞的數(shù)據(jù)也可說(shuō)是參數(shù).

b.接收通知也就是注冊(cè)通知

[[NSNotificationCenter defaultCenter]addObserver:selfselector:@selector(changeValue:) name:@"data"object:nil];

addObserver :是要接收通知者elector:@selector(changeValue:)傳遞數(shù)據(jù)的方法name:是消息的標(biāo)識(shí)假如是nil的話就是什么消息都會(huì)接收object:是要發(fā)出者假如是nil的話誰(shuí)的消息都會(huì)接收

3.這就是實(shí)現(xiàn)數(shù)據(jù)傳遞的方法:

-(void)changeValue:(NSNotification *)notification{

NSDictionary *dic = [notification userInfo];

NSString *str = [dic objectForKey:@"mimi"];

self.textF.text = str;

}

12.屬性傳遞消息

接受者設(shè)置屬性

同時(shí)在發(fā)出者有數(shù)據(jù)的時(shí)候?qū)⒃摂?shù)據(jù)的值賦值給該屬性;

13.代理

1.設(shè)置一個(gè)協(xié)議并且要有一個(gè)傳遞數(shù)據(jù)的方法

2.發(fā)消息者設(shè)置一個(gè)代理屬性

3.在接收消消息者和發(fā)消息者同時(shí)出現(xiàn)的時(shí)候設(shè)置代理并且接收者需要遵守該協(xié)議即發(fā)出者.delegate =接受者;

4.接收者實(shí)現(xiàn)數(shù)據(jù)傳遞的方法

5.發(fā)消息者調(diào)用實(shí)現(xiàn)數(shù)據(jù)傳遞的方法.

14.控制器跳轉(zhuǎn):

1.modal跳轉(zhuǎn)

方法: presentViewController:/*需要跳轉(zhuǎn)的控制器(nonnull UIViewController *) */animated:(YES) completion:^{

跳轉(zhuǎn)之后執(zhí)行的方法

}

通過(guò)dismissViewControllerAnimated來(lái)返回前一個(gè)界面的渔隶。這是返回前一個(gè)界面的.

2.push POP跳轉(zhuǎn)

a.是給一根segua線綁定標(biāo)識(shí)在獲取跳轉(zhuǎn)的目標(biāo)控制器

//就是這種模式OYVC *vc = segue.destinationViewController;

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

OYVC *vc = segue.destinationViewController;

}

//再調(diào)用這個(gè)方法來(lái)實(shí)現(xiàn)跳轉(zhuǎn)

- (IBAction)go:(id)sender {

[selfperformSegueWithIdentifier:@"go"sender:nil];

}

//用代碼創(chuàng)建的

+ (instancetype)segueWithIdentifier:(nullableNSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination performHandler:(void(^)(void))performHandler NS_AVAILABLE_IOS(6_0);

- (instancetype)initWithIdentifier:(nullableNSString *)identifier source:(UIViewController *)source destination:(UIViewController *)destination NS_DESIGNATED_INITIALIZER;

b.回跳的話

[self.navigationController popViewControllerAnimated:YES];等方法

通過(guò)dismissViewControllerAnimated來(lái)返回前一個(gè)界面的羔挡。這是返回前一個(gè)界面的.也可以.

3、通過(guò)導(dǎo)航控制器UINavigationController

導(dǎo)航控制器:絕對(duì)是最常用的跳轉(zhuǎn)方法间唉,也是大家最熟悉的一種方式绞灼。每個(gè)控制器對(duì)象都有一個(gè)NavigationController屬性,NavigationController的view的是由導(dǎo)航條呈野,導(dǎo)航條控制的view,和棧頂控制器的view組成的低矮。

工作原理:通過(guò)棧的方式的來(lái)實(shí)現(xiàn)的,NavigationController展示永遠(yuǎn)就是棧頂?shù)目刂破鞯膙iew被冒。當(dāng)使用push方法的時(shí)候军掂,就將需要跳轉(zhuǎn)的控制器壓入棧中轮蜕,成為棧頂控制器;當(dāng)使用pop方法的時(shí)候良姆,就將控制器移出棧肠虽,原來(lái)跳轉(zhuǎn)之前的控制器重新成為棧頂控制器幔戏,被展現(xiàn)玛追;

需要注意的是:跳轉(zhuǎn)的時(shí)候,跳轉(zhuǎn)前的控制器不會(huì)移除闲延;導(dǎo)航欄(UINavigationBar)的屬性由棧頂控制器來(lái)決定痊剖。UINavigationBar支持appearance統(tǒng)一設(shè)置,但UINavigationItem不支持;

涉及到的類(lèi)詳解:

UINavigationBar :繼承至UIView垒玲,NavigaitonBar就是導(dǎo)航欄陆馁,位于屏幕的上方,管理整個(gè)NavigationController的navigationItem合愈,即類(lèi)似navigationcontroller一樣提供了一個(gè)棧來(lái)管理item叮贩。

UINavigationItem :繼承至NSObject,通過(guò)這個(gè)屬性來(lái)設(shè)置title佛析,prompt益老,leftBarButtonItem,titleView寸莫,,rightBarButtonItem捺萌,backBarButonItem等。

UIBarButtonItem :繼承至UIBarItem膘茎,UIBarItem繼承至UIButton桃纯。專(zhuān)門(mén)用來(lái)放在UIToolbar或者UINavigationBar的特殊button。

總結(jié):NavigationController直接控制ViewControllers披坏,并包含NavigaitonBar态坦。NavigaitonBar包含整個(gè)UINavigationItem的棧,管理整個(gè)NavigationController的UINavigationItem(NSArray *items屬性)棒拂。UINavigationItem包含了NavigaitonBar視圖的全部元素(如title,tileview,backBarButtonItem等)驮配,又受當(dāng)前棧頂控制器管理,即NavigaitonBar形成整個(gè)NavigationController的導(dǎo)航視圖着茸,然后每個(gè)NavigationController頁(yè)面的導(dǎo)航欄元素由所在頁(yè)面的UINavigationItem管理壮锻。即設(shè)置當(dāng)前頁(yè)面的左右barbutton。

4涮阔、UITabBarController

tabbar控制器猜绣,同樣是常用的界面切換方式,一般作為app的根界面的視圖控制器敬特。其實(shí)與其說(shuō)UITabBarController的界面跳轉(zhuǎn)掰邢,不如說(shuō)是界面切換牺陶,因?yàn)閁ITabBarController的界面跳轉(zhuǎn)其實(shí)就是UITabBarController的viewControllers數(shù)組中的幾個(gè)界面切換。只要設(shè)置好了UITabBarController的viewControllers數(shù)組就可以了辣之。也可以工廠自定義tabbar掰伸,通過(guò)selectedItem來(lái)控制。

結(jié)構(gòu)也類(lèi)似NavigationController

tableBar的添加底部的控制器有View Controllers添加子控制器.

15.通過(guò)storyboard加載控制器的方法

// Name:storyboard文件名

// nil = [NSBundle mainBundle]

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main"bundle:nil];

//加載Main.storyboard描述的控制器

// instantiateInitialViewController:加載箭頭指向的控制器

UIViewController *vc = [storyboard instantiateInitialViewController];

/通過(guò)xib加載控制器的步驟

// 1.創(chuàng)建xib文件

// 2.xib拖一個(gè)view去描述控制器的view!!!!!重點(diǎn)

// 3.告訴xib是描述控制器,設(shè)置file'owner為控制器,可以往控制器中拖線

// 4.連線,告訴控制器哪個(gè)view描述你的view

16.pch原理:會(huì)把pch里面的所有內(nèi)容導(dǎo)入到每個(gè)文件中去

pch作用:

1.pch存放公用的宏

2.pch存放公用的頭文件,分類(lèi)的頭文件

3.pch可以自定義Log

pch注意點(diǎn):

判斷下當(dāng)前是否是OC文件

*/

//每一個(gè)OC文件都會(huì)定義這個(gè)宏__OBJC__

#ifdef __OBJC__

//放OC

#import"UIImage+Image.h"

#define ABC 10

//判斷系統(tǒng)的版本號(hào)

#define iOS8([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)

#define iPhone5 ([UIScreen mainScreen].bounds.size.height == 568)

//程序在調(diào)試階段的時(shí)候才需要打印

#ifdef DEBUG//調(diào)試階段

// ...表示宏里面的可變參數(shù)

// __VA_ARGS__函數(shù)里面可變參數(shù)

#define XMGLog(...)NSLog(__VA_ARGS__)

#else//發(fā)布階段

#define XMGLog(...)

#endif

16.日期的格式

NSDateFormatter *fmt = [[NSDateFormatter alloc] init];

fmt.dateFormat =@"yyyy-MM-dd";

NSDate *date = [fmt dateFromString:@"1990-1-1"];

方法自己摸索一步步去理解

17.開(kāi)啟上下文模式(Quartz2D)

Quartz提供了5種類(lèi)型的Graphics Context怀估。Bitmap Graphics Context狮鸭、PDF Graphics Context、Window Graphics Context多搀、Layer Context概漱、Post Graphics Context壁顶。

a.圖形上下文

一定會(huì)執(zhí)行drawRect方法并且還要重繪[selfsetNeedsDisplay].

1.獲得圖形上下文2.設(shè)置繪畫(huà)路徑3將路徑描述好4將路徑添加到上下文中5將上下文渲染到圖中

// 1.獲取上下文

CGContextRef ctx= UIGraphicsGetCurrentContext();

// 2.設(shè)置繪圖信息/拼接路徑

UIBezierPath *path = [UIBezierPath bezierPath];

// 3.設(shè)置一個(gè)起點(diǎn)

[path moveToPoint:CGPointMake(10,10)];

// 4.添加一條直線到一個(gè)點(diǎn)

[path addLineToPoint:CGPointMake(100,100)];

// 5.添加一條直線到一個(gè)點(diǎn)

[path addLineToPoint:CGPointMake(150,60)];

// 5.把路徑添加到上下文

CGContextAddPath(ctx, path.CGPath);

// 6.把上下文渲染到視圖

CGContextStrokePath(ctx);

// stroke:描邊

// fill:填充

//設(shè)置線的樣式

CGContextSetLineJoin(ctx, kCGLineJoinBevel);

//設(shè)置頂角樣式

CGContextSetLineCap(ctx, kCGLineCapRound);

Current transformation matrix (CTM):當(dāng)前轉(zhuǎn)換矩陣

Clipping area:裁剪區(qū)域

Line:線

Accuracy of curve estimation (flatness):曲線平滑度

Anti-aliasing setting:反鋸齒設(shè)置

Color:顏色

Alpha value (transparency):透明度

Rendering intent:渲染目標(biāo)

Color space:顏色空間

Text:文本

Blend mode:混合模式

CGPathRef:用于向量圖堂油,可創(chuàng)建路徑披粟,并進(jìn)行填充或描畫(huà)(stroke)

CGImageRef:用于表示bitmap圖像和基于采樣數(shù)據(jù)的bitmap圖像遮罩。

CGLayerRef:用于表示可用于重復(fù)繪制(如背景)和幕后(offscreen)繪制的繪畫(huà)層

CGPatternRef:用于重繪圖

CGShadingRef从藤、CGGradientRef:用于繪制漸變

CGFunctionRef:用于定義回調(diào)函數(shù)催跪,該函數(shù)包含一個(gè)隨機(jī)的浮點(diǎn)值參數(shù)。當(dāng)為陰影創(chuàng)建漸變時(shí)使用該類(lèi)型

CGColorRef, CGColorSpaceRef:用于告訴Quartz如何解釋顏色

CGImageSourceRef,CGImageDestinationRef:用于在Quartz中移入移出數(shù)據(jù)

CGFontRef:用于繪制文本

CGPDFDictionaryRef,CGPDFObjectRef,CGPDFPageRef,CGPDFStream, CGPDFStringRef, and CGPDFArrayRef:用于訪問(wèn)PDF的元數(shù)據(jù)

CGPDFScannerRef, CGPDFContentStreamRef:用于解析PDF元數(shù)據(jù)

CGPSConverterRef:用于將PostScript轉(zhuǎn)化成PDF夷野。在iOS中不能使用懊蒸。

2.位圖上下文:

// 1.開(kāi)啟上下文

UIGraphicsBeginImageContextWithOptions(view.bounds.size,NO,0.0);

// 2.獲取當(dāng)前上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

// 3.把控制器圖層渲染到上下文

[view.layer renderInContext:ctx];

// 4.取出新圖片

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

//圖片保存到本地相冊(cè)的方法:::

UIImageWriteToSavedPhotosAlbum(newImage,self,@selector(image:didFinishSavingWithError:contextInfo:),nil);

//當(dāng)寫(xiě)入完成時(shí)調(diào)用即是照片讀取完畢后會(huì)進(jìn)來(lái)

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void*)contextInfo {

NSLog(@"saveCom");

}

- (IBAction)photo:(id)sender {

//彈出系統(tǒng)相冊(cè)選擇照片

UIImagePickerController *pickVC = [[UIImagePickerController alloc] init];

//設(shè)置照片來(lái)源

pickVC.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;

//只要實(shí)現(xiàn)代理方法,必須得要手去關(guān)閉控制器

pickVC.delegate =self;

//modal

[selfpresentViewController:pickVC animated:YEScompletion:nil];

}

//選擇照片完畢后會(huì)進(jìn)來(lái)

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

NSLog(@"%@",info);

UIImage *image = info[UIImagePickerControllerOriginalImage];

//NSData *data = UIImagePNGRepresentation(image);

//[data writeToFile:@"/Users/apple/Desktop/choose.png" atomically:YES];

HanleImageUIView *hanleV = [[HanleImageUIView alloc] init];

hanleV.frame =self.drawView.frame;

hanleV.backgroundColor = [UIColor clearColor];

hanleV.image = image;

hanleV.delegate =self;

[self.view addSubview:hanleV];

//把選擇圖片繪制畫(huà)板當(dāng)中

//self.drawView.image = image;

[selfdismissViewControllerAnimated:YEScompletion:nil];

}

18.cell釋放池的問(wèn)題cell能夠重復(fù)利用

當(dāng)前tableview界面當(dāng)當(dāng)一個(gè)消失后一個(gè)出現(xiàn)的時(shí)候后一個(gè)的內(nèi)存地址就是第一個(gè)的內(nèi)存地址這樣就解決了內(nèi)存地址的問(wèn)題就會(huì)有重用機(jī)制這樣的話內(nèi)存就會(huì)大大的減少

//cell的創(chuàng)建系統(tǒng)的釋放池內(nèi)

UITableViewCell *cell= [tableView dequeueReusableCellWithIdentifier:ID];

//判斷釋放池內(nèi)有沒(méi)有cell

//第一種方式

if( !cell ) {

cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID];

}

//第二種注冊(cè)的方式

1.類(lèi)的注冊(cè)

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];

2.xib的注冊(cè)

[self.tableView registerNib:<#(nullable UINib *)#> forCellReuseIdentifier:ID];

//第三種是自己自定義cell可以在xib或者storyBoard里面設(shè)置cell的標(biāo)識(shí)

//分割線顏色

self.tableView.separatorColor = [UIColor redColor];

//隱藏分割線

self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

//自定義不等高cell的做法

在模型中增加一個(gè)cellHeight屬性,用來(lái)存放對(duì)應(yīng)cell的高度

在cell的模型屬性set方法中調(diào)用[selflayoutIfNeed]方法強(qiáng)制布局扫责,然后計(jì)算出模型的cellheight屬性值

在控制器中實(shí)現(xiàn)tableView:estimatedHeightForRowAtIndexPath:方法榛鼎,返回一個(gè)估計(jì)高度,比如200

在控制器中實(shí)現(xiàn)tableView:heightForRowAtIndexPath:方法鳖孤,返回cell的真實(shí)高度(模型中的cellHeight屬性

19.單粒單例模式的替代一勞永逸

#define SingleH(name) +(instancetype)share##name;

#if __has_feature(objc_arc)

///ARC

#define SingleM(name) static id_instance;\

+(instancetype)allocWithZone:(struct _NSZone *)zone\

{\

static dispatch_once_t onceToken;\

dispatch_once(&onceToken, ^{\

_instance = [super allocWithZone:zone];\

});\

return _instance;\

}\

+(instancetype)share##name\

{\

return [[self alloc]init];\

}\

-(id)copyWithZone:(NSZone *)zone\

{\

return _instance;\

}\

\

-(id)mutableCopyWithZone:(NSZone *)zone\

{\

return _instance;\

}

#else

//MRC

#define SingleM(name) static id_instance;\

+(instancetype)allocWithZone:(struct _NSZone *)zone\

{\

static dispatch_once_t onceToken;\

dispatch_once(&onceToken, ^{\

_instance = [super allocWithZone:zone];\

});\

return _instance;\

}\

+(instancetype)share##name\

{\

return [[self alloc]init];\

}\

-(id)copyWithZone:(NSZone *)zone\

{\

return _instance;\

}\

\

-(id)mutableCopyWithZone:(NSZone *)zone\

{\

return _instance;\

}\

-(oneway void)release\

{}\

\

-(instancetype)retain\

{\

return _instance;\

}\

\

-(NSUInteger)retainCount\

{\

return MAXFLOAT;\

}

#endif

19.沙盒

Documents :會(huì)備份&不允許(X)//很重要

Library

caches

perference偏好設(shè)置

tmp :臨時(shí)數(shù)據(jù)

4.數(shù)據(jù)存儲(chǔ)

1.Documents

獲取方法:NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES)[0];

//存放重要數(shù)據(jù).iTunes同步設(shè)備時(shí)會(huì)備份

2.tmp

獲取方法:NSTemporaryDirectory();

//存放臨時(shí)文件,系統(tǒng)會(huì)隨機(jī)刪除

3.Caches

獲取方法:NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask,YES)[0];

//存放大體積,不必要備份文件

4.Preferences

獲取方法:[NSUserDefaults standardUserDefaults]

//存放少量數(shù)據(jù).iTunes同步設(shè)備時(shí)會(huì)備份

2.數(shù)據(jù)存儲(chǔ)

1.plist

pilst只支持系統(tǒng)自帶的類(lèi)型(如:NSString,NSArray,NSDictionary,NSData,NSNumber等)

1.寫(xiě)入:writeToFile

2.讀取:...WithContentOfFile(如:arrayWithContentOfFile)

2.偏好設(shè)置

1.取得偏好設(shè)置對(duì)象(NSUserDefaults)

NSUserDefaults *def = [NSUserDefaults standardUserDefaults];

2.寫(xiě)入到文件夾

[def setObject:obj forKey:key];//oc類(lèi)對(duì)應(yīng)setObject,bool類(lèi)型對(duì)應(yīng)setBool等...

3.讀取內(nèi)容

[def objectForKey:obj];//oc類(lèi)對(duì)應(yīng)object,NSInteger對(duì)應(yīng)integer等...

3.歸檔

1.寫(xiě)入用NSKeyedArchjver

1.選擇要存儲(chǔ)的位置(filePath)

2.系統(tǒng)自帶類(lèi)(如:NSArray,NSDictionary)直接使用

3.自定義類(lèi)需遵守NSCoding協(xié)議,并重寫(xiě)encodeWithCoder方法(例子為name屬性)

-(void)encodeWithCoder:(NSCoder *)aCoder{

[aCoder encodeObject:self.name forKey:@"name"];

}

4.調(diào)用[NSKeyedArchjver archiveRootObject:object toFile:filePath];

2.讀取用NSKeyedUnArchjver

1.獲取要讀取文件的位置(filePath)

2.系統(tǒng)自帶類(lèi)(如:NSArray,NSDictionary)直接使用

3.自定義類(lèi)需遵守NSCoding協(xié)議,并重寫(xiě)initWithCoder方法(例子為name屬性)

-(instancetype)initWithCoder:(NSCoder *)aDecoder{

if(self= [superinit]){

self.name = [aDecoder decodeObjectForKey:@"name"];

}

returnself;

}

4.調(diào)用[NSKeyedUnArchjver unarchiveObjectWithFile:filePath]

歸檔:自定義對(duì)象一般使用歸檔,為什么自定義對(duì)象需要?dú)w檔,plist存儲(chǔ)不能存儲(chǔ)自定義對(duì)象其實(shí)際操作跟字典差不多就是得遵守nscoding的協(xié)議

- (void)encodeWithCoder:(NSCoder *)aCoder;

- (nullableinstancetype)initWithCoder:(NSCoder *)aDecoder;

假如你要存檔和解檔的話都要寫(xiě)這兩個(gè)方法方法也要看著屬性的類(lèi)型進(jìn)去解歸檔.

要使用歸檔的話都要遵守nscoding這個(gè)協(xié)議

首先進(jìn)行保存的操作:就是將數(shù)據(jù)讀取進(jìn)去假如寫(xiě)入模型的時(shí)候要進(jìn)行一

如何進(jìn)行解檔的操作

解析文件的時(shí)候調(diào)用

//作用:解析xib,storyboard調(diào)用

- (id)initWithCoder:(NSCoder *)aDecoder

{

//這里必須調(diào)用[super initWithCoder:aDecoder],super ->UIView

//什么時(shí)候調(diào)用[super initWithCoder:aDecoder],只要父類(lèi)遵守了NSCoding協(xié)議,就調(diào)用[super initWithCoder:aDecoder]

if(self= [superinitWithCoder:aDecoder]) {

NSLog(@"%s",__func__);

}

returnself;

}

20.下載圖片的整體思路:

1.首先判斷內(nèi)存緩存有沒(méi)有圖片2假如沒(méi)有的話就要保存到內(nèi)存中3在保存中還要看它有沒(méi)有在子線程中如果在的話啥都不做不在的話就要?jiǎng)?chuàng)建子線程將圖片下載的過(guò)程加到子隊(duì)列中而且還要檢查圖片是不是為空不然的話會(huì)一直有任務(wù)在進(jìn)行就會(huì)一直開(kāi)子進(jìn)程在子進(jìn)程中還要跳轉(zhuǎn)到主進(jìn)程去顯示圖片最后將子進(jìn)程添加到隊(duì)列中并且保存隊(duì)列到字典中去進(jìn)行下一次判斷子進(jìn)程還要不要開(kāi)就是執(zhí)行中任務(wù)有沒(méi)有不然會(huì)造成任務(wù)多次運(yùn)行.

//假如圖片為空的話移除所有隊(duì)列里面的加載

if(newImage ==nil) {

[self.opearations removeObjectForKey:item.icon];

}

[self.images setValue:newImage forKey:item.icon];

[data writeToFile:filePath atomically:YES];

//刷新tabelView的方法

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

[self.tableView reloadRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationTop];

}];

1)UI卡頓--->開(kāi)子線程下載圖片

圖片不顯示(fram=0)--->刷新指定的行

重復(fù)下載的問(wèn)題(因?yàn)閳D片下載操作需要花費(fèi)時(shí)間,在該時(shí)間段內(nèi)部此image有需要顯示)

對(duì)圖片的下載操作進(jìn)行緩存--->操作緩存

2)重復(fù)下載的問(wèn)題-->內(nèi)存緩存

*/

//二級(jí)緩存

/*

顯示-->內(nèi)存緩存-->下載

顯示-->內(nèi)存緩存-->磁盤(pán)緩存-->下載

*/

21.SDWebImage下載圖片框架的作用:

1).為cocoa touch提供一個(gè)UIimageView的分類(lèi),加載圖片并進(jìn)行緩存處理

2).異步下載圖片

3).異步存儲(chǔ)器+具備自動(dòng)緩存過(guò)程處理的磁盤(pán)映像緩存

4).支持GIF播放

5).支持WebP格式

6).背景圖片解壓縮

7).保證同一個(gè)圖片Url不被多次下載

8).保證錯(cuò)誤的URL不被反復(fù)下載

9).保證不會(huì)阻塞主線程

10).高性能

11).使用GCD和ARC機(jī)制

12).支持Ara64架構(gòu)

/*

1)clear先把之前的緩存文件夾刪除,然后重新創(chuàng)建一個(gè)新的文件夾是暴力刪除

clean先刪除過(guò)期的文件,然后計(jì)算剩余緩存文件的大小(currrentSize)>maxSize,繼續(xù)刪除(按照緩存文件創(chuàng)建的時(shí)間順序來(lái)刪除的),直到currrentSize <= maxSize

2)默認(rèn)過(guò)期時(shí)間:1個(gè)星期

3)內(nèi)存緩存機(jī)制(用什么來(lái)做內(nèi)存緩存?是字典嗎?) NSCache是專(zhuān)門(mén)用來(lái)做緩存處理的

4)最大并發(fā)數(shù)量maxConcurrentOperationCount = 6

5)隊(duì)列中任務(wù)的執(zhí)行方式:

SDWebImageDownloaderExecutionOrder

SDWebImageDownloaderFIFOExecutionOrder(FIFO)默認(rèn)

SDWebImageDownloaderLIFOExecutionOrder(lIFO)(通過(guò)設(shè)置依賴來(lái)實(shí)現(xiàn))

6)默認(rèn)的緩存路徑:~/Library/Caches/default/com.hackemist.SDWebImageCache.default/...

7)圖片保存的名稱(chēng)處理方式:url進(jìn)行MD5加密echo -n "url" | md5

8)播放GIF圖片, GIF圖片播放原理ImageIO

9)如何判斷圖片的類(lèi)型:得到圖片的二進(jìn)制數(shù)據(jù)的第一個(gè)字節(jié)

10)該框架內(nèi)部通過(guò)NSURLConnection建立網(wǎng)絡(luò)連接發(fā)送請(qǐng)求下載圖片

11)默認(rèn)的請(qǐng)求超時(shí)的時(shí)間是_downloadTimeout = 15

12)該框架內(nèi)部對(duì)內(nèi)存警告的處理方式:內(nèi)部會(huì)監(jiān)聽(tīng)系統(tǒng)發(fā)出的系統(tǒng)警告通知,然后清理內(nèi)存緩存

13)NSCache使用方法和可變的字典類(lèi)似(80%),線程安全&可以自動(dòng)的清理緩存數(shù)據(jù)

14)計(jì)算圖片的成本:image.size.height * image.size.width * image.scale * image.scale

15)保證錯(cuò)誤url不被反復(fù)嘗試下載?內(nèi)部設(shè)置了一個(gè)url黑名單NSMutableSet

*/

下載圖片框架的使用:

1.1)下載圖片并顯示(內(nèi)存緩存&磁盤(pán)緩存)

/*

第一個(gè)參數(shù):圖片的url地址

第二個(gè)參數(shù):設(shè)置的占位圖片

*/

[self.imageView sd_setImageWithURL:[NSURL URLWithString:URL] placeholderImage:[UIImage imageNamed:image]];

2.下載圖片顯示并計(jì)算下載進(jìn)度(內(nèi)存緩存&磁盤(pán)緩存&下載進(jìn)度)

/*

第一個(gè)參數(shù):圖片的url地址

第二個(gè)參數(shù):設(shè)置的占位圖片

第三個(gè)參數(shù):下載圖片選項(xiàng)(策略)

第四個(gè)參數(shù):進(jìn)度回調(diào)blockreceivedSize:已經(jīng)下載的數(shù)據(jù)大小expectedSize:圖片的總大小

第五個(gè)參數(shù):completed圖片下載結(jié)束回調(diào)(成功|失斦哂椤)

image:下載后得到的圖片,如果下載失敗苏揣,那么image的值為nil

error:錯(cuò)誤信息黄鳍,如果失敗,則error有值

cacheType:圖片來(lái)源(枚舉:內(nèi)存緩存|磁盤(pán)緩存|直接下載)

imageURL:下載圖片的url

*/

sd_setImageWithURL:[NSURL URLWithString:url]placeholderImage:[UIImage imageNamed:占位圖片] options:SDWebImageProgressiveDownload progress:^(NSInteger receivedSize, NSInteger expectedSize) {

NSLog(@"%f",1.0* receivedSize/expectedSize);//進(jìn)度值得算法

} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

}

3)下載圖片不顯示并監(jiān)聽(tīng)下載進(jìn)度(內(nèi)存緩存&磁盤(pán)換次&下載進(jìn)度)

-(void)download3

{

//使用管理者下載圖片

[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:URL] options:0progress:^(NSInteger receivedSize, NSInteger expectedSize) {

} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType,BOOLfinished, NSURL *imageURL) {

NSLog(@"+++++%@",[NSThread currentThread]);

self.imageView.image = image;

switch(cacheType) {

caseSDImageCacheTypeNone:

NSLog(@"直接下載");

break;

caseSDImageCacheTypeDisk:

NSLog(@"磁盤(pán)緩存");

break;

caseSDImageCacheTypeMemory:

NSLog(@"內(nèi)存緩存");

break;

default:

break;

}

}];

}

4)下載圖片不顯示且不做任何的緩存處理

-(void)download4

{

[[SDWebImageDownloader sharedDownloader] downloadImageWithURL:[NSURL URLWithString:動(dòng)圖的URL ] options:0progress:^(NSInteger receivedSize, NSInteger expectedSize) {

NSLog(@"%f",1.0* receivedSize/expectedSize);

} completed:^(UIImage *image, NSData *data, NSError *error,BOOLfinished) {

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

self.imageView.image = [UIImage sd_animatedGIFWithData:data];

}];

}];

}

5)接收到系統(tǒng)級(jí)內(nèi)存警告時(shí)如何處理(面試)

//(1)取消當(dāng)前正在進(jìn)行的所有下載操作

[[SDWebImageManager sharedManager] cancelAll];

//(2)清除緩存數(shù)據(jù)

//cleanDisk:刪除過(guò)期的文件數(shù)據(jù)平匈,計(jì)算當(dāng)前未過(guò)期的已經(jīng)下載的文件數(shù)據(jù)的大小框沟,如果發(fā)現(xiàn)該數(shù)據(jù)大小大于我們?cè)O(shè)置的最大緩存數(shù)據(jù)大小,那么程序內(nèi)部會(huì)按照按文件數(shù)據(jù)緩存的時(shí)間從遠(yuǎn)到近刪除增炭,知道小于最大緩存數(shù)據(jù)為止忍燥。

//clearMemory:直接刪除文件,重新創(chuàng)建新的文件夾

//[[SDWebImageManager sharedManager].imageCache cleanDisk];

[[SDWebImageManager sharedManager].imageCache clearMemory];

6)播放gif圖片

(1)播放GiF圖片部分過(guò)程解析

a.把用戶傳入的gif圖片->NSData

b.根據(jù)該Data創(chuàng)建一個(gè)圖片數(shù)據(jù)源(NSData->CFImageSourceRef)

c.計(jì)算該數(shù)據(jù)源中一共有多少幀隙姿,把每一幀數(shù)據(jù)取出來(lái)放到圖片數(shù)組中

d.根據(jù)得到的數(shù)組+計(jì)算的動(dòng)畫(huà)時(shí)間-》可動(dòng)畫(huà)的image

e.[UIImage animatedImageWithImages:images duration:duration];

(2)如何使用

-(void)gif

{

//self.imageView.image = [UIImage imageNamed:@"123"];不可用

UIImage *image = [UIImage sd_animatedGIFNamed:@"123"];

self.imageView.image = image;

}

22.NSCache與NSDictionary的對(duì)比:要遵守代理的哦

1.NSCache可以設(shè)置代理

2.NSCache可以設(shè)置緩存的成本即當(dāng)超過(guò)了這個(gè)成本的時(shí)候會(huì)自動(dòng)刪除從前往后刪.

3.NSCache的線程是安全的

totalCostLimit:緩存空間的最大總成本梅垄,超出上限會(huì)自動(dòng)回收對(duì)象。默認(rèn)值為0输玷,表示沒(méi)有限制

countLimit:能夠緩存的對(duì)象的最大數(shù)量队丝。默認(rèn)值為0靡馁,表示沒(méi)有限制

evictsObjectsWithDiscardedContent:標(biāo)識(shí)緩存是否回收廢棄的內(nèi)容

//NSCache的基本使用(如何存數(shù)據(jù)|如何取數(shù)據(jù))~和可變字典類(lèi)似

當(dāng)內(nèi)部開(kāi)始清理數(shù)據(jù)的時(shí)候調(diào)用

-(void)cache:(NSCache *)cache willEvictObject:(id)obj;

23.新版本特性界面控制器

1.根據(jù)對(duì)應(yīng)版本號(hào)來(lái)確定是否新特性界面控制器

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

//2.設(shè)置根控制器

//2.1根據(jù)當(dāng)前版本和上一次的版本進(jìn)行判斷

//2.2獲取當(dāng)前版本號(hào)

NSString *curVersion = [NSBundle mainBundle].infoDictionary[@"CFBundleShortVersionString"];

//2.3獲取上一次的版本號(hào)

NSString *lastVersion = [[NSUserDefaults standardUserDefaults]objectForKey:@"version"];

//2.4根據(jù)比較確定是否存儲(chǔ)版本

if([curVersion isEqualToString:lastVersion]) {

XMGMainVc *mainVc = [[XMGMainVc alloc]init];

self.window.rootViewController = mainVc;

//

}else{//存儲(chǔ)版本,當(dāng)前版本和上一次不一樣,顯示新特性界面

NSUserDefaults *defaultData = [NSUserDefaults standardUserDefaults];

[defaultData setObject:curVersion forKey:@"version"];

[defaultData synchronize];

XMGNewFeatureVc *newVc = [[XMGNewFeatureVc alloc]init];

self.window.rootViewController = newVc;

}

//3.可見(jiàn)

[self.window makeKeyAndVisible];

24.位移枚舉

1.//純C語(yǔ)言風(fēng)格

typedefenum: NSUInteger {

MyEnumValueA,

MyEnumValueB,

MyEnumValueC,

} myType;

//純OC語(yǔ)言風(fēng)格

typedefNS_ENUM(NSUInteger, myOCType) {

MyEnumValue1,

MyEnumValue2,

MyEnumValue3,

};

//位移枚舉

typedefNS_OPTIONS(NSUInteger, myWeiYiType) {

MyEnumValueA1 =1<<0,

MyEnumValueB2 =1<<1,

MyEnumValueC3 =1<<2,

};

2.位移枚舉相關(guān)說(shuō)明

特點(diǎn):通過(guò)使用位移枚舉可以實(shí)現(xiàn)一個(gè)參數(shù)實(shí)現(xiàn)傳遞多個(gè)操作

原理:按位與只要有0則為0机久,按位或只要有1則為1

技巧:如果位移枚舉的第一個(gè)選項(xiàng)為0臭墨,那么在傳遞參數(shù)的時(shí)候默認(rèn)可以傳0,傳0性能最優(yōu)膘盖,不做額外的操作

25.NSTimer和GCD的定時(shí)器有什么區(qū)別胧弛?

1.GCD的定時(shí)器比nstimer更加精確

2.GCD的定時(shí)器不用依賴runloop而nstimer沒(méi)有加入到runloop中將不會(huì)運(yùn)行

3.[NSTimer scheduledTimerWithTimeInterval:3.0target:selfselector:@selector(task) userInfo:nilrepeats:YES];//默認(rèn)已經(jīng)添加到runloop中

假如不用這個(gè)方法就要加到runLoop中;

4.

//1.創(chuàng)建一個(gè)GCD的定時(shí)器

/*

第一個(gè)參數(shù):DISPATCH_SOURCE_TYPE_TIMER定時(shí)器

第二個(gè)參數(shù):描述信息

第三個(gè)參數(shù):總是穿0

第四個(gè)參數(shù):隊(duì)列(決定GCD要執(zhí)行的任務(wù)在哪個(gè)線程中調(diào)用的并發(fā)隊(duì)列--子線程中調(diào)用)

*/

dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0, dispatch_get_main_queue());

//2.設(shè)置定時(shí)器

/*

第一個(gè)參數(shù):定時(shí)器對(duì)象

第二個(gè)參數(shù):從什么時(shí)候開(kāi)始計(jì)時(shí)DISPATCH_TIME_NOW現(xiàn)在

第三個(gè)參數(shù):間隔時(shí)間2.0 ns

第四個(gè)參數(shù):精準(zhǔn)度允許的誤差絕對(duì)精準(zhǔn)~0

*/

//dispatch_time_t t = dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC);

dispatch_source_set_timer(timer, DISPATCH_TIME_NOW,2.0* NSEC_PER_SEC,0* NSEC_PER_SEC);

//3.設(shè)置定時(shí)器的任務(wù)

dispatch_source_set_event_handler(timer, ^{

NSLog(@"==GCD===%@",[NSThread currentThread]);//任務(wù)塊

});

//4.恢復(fù)定時(shí)器

dispatch_resume(timer);

//一定要這句要強(qiáng)應(yīng)用它不然創(chuàng)建的定時(shí)器對(duì)象就會(huì)掛掉

self.timer = timer;

26.Runloop原理:

1.程序一啟動(dòng)就會(huì)有一個(gè)主runloop開(kāi)啟

2)在iOS開(kāi)發(fā)中有兩套api來(lái)訪問(wèn)Runloop

a.foundation框架[NSRunloop]

b.core foundation框架[CFRunloopRef]互換的格式是例如: mainRunloop.getCFRunLoop

2./子線程和runloop的關(guān)系

/*

1)一一對(duì)應(yīng)的

2)主線程對(duì)應(yīng)的runloop默認(rèn)已經(jīng)開(kāi)啟了,子線程對(duì)應(yīng)的runloop需要主動(dòng)創(chuàng)建

3)如何創(chuàng)建子線程對(duì)應(yīng)的runloop :[NSRunLoop currentRunLoop](該方法本身是懶加載的,第一次調(diào)用該方法的時(shí)候如果發(fā)現(xiàn)runloop不存在那么會(huì)直接創(chuàng)建一個(gè))

4)runloop是需要開(kāi)啟

*/

3.a.CFRunloopRef//創(chuàng)建runloop對(duì)象

b.CFRunloopModeRef【Runloop的運(yùn)行模式】

c.CFRunloopSourceRef【Runloop要處理的事件源】

d.CFRunloopTimerRef【Timer事件】

e.CFRunloopObserverRef【Runloop的觀察者(監(jiān)聽(tīng)者)】

注意點(diǎn):

01.CFRunloopModeRef代表著Runloop的運(yùn)行模式

02.一個(gè)Runloop中可以有多個(gè)mode,一個(gè)mode里面又可以有多個(gè)source\observer\timer等等

03.每次runloop啟動(dòng)的時(shí)候,只能指定一個(gè)mode,這個(gè)mode被稱(chēng)為該Runloop的當(dāng)前mode

04.如果需要切換mode,只能先退出當(dāng)前Runloop,再重新指定一個(gè)mode進(jìn)入

05.這樣做主要是為了分割不同組的定時(shí)器等衔憨,讓他們相互之間不受影響

06.系統(tǒng)默認(rèn)注冊(cè)了5個(gè)mode

a.kCFRunLoopDefaultMode:App的默認(rèn)Mode叶圃,通常主線程是在這個(gè)Mode下運(yùn)行

b.UITrackingRunLoopMode:界面跟蹤Mode袄膏,用于ScrollView追蹤觸摸滑動(dòng)践图,保證界面滑動(dòng)時(shí)不受其他Mode影響

c.UIInitializationRunLoopMode:在剛啟動(dòng)App時(shí)第進(jìn)入的第一個(gè)Mode,啟動(dòng)完成后就不再使用

d.GSEventReceiveRunLoopMode:接受系統(tǒng)事件的內(nèi)部Mode沉馆,通常用不到

e.kCFRunLoopCommonModes:這是一個(gè)占位用的Mode码党,不是一種真正的Mode

CFRunLoopObserverRef//觀察者

這個(gè)僅供內(nèi)部參考實(shí)際開(kāi)發(fā)中基本用不到

1.創(chuàng)建監(jiān)聽(tīng)者

/*

第一個(gè)參數(shù):分配存儲(chǔ)空間

第二個(gè)參數(shù):告知要監(jiān)聽(tīng)的是哪種狀態(tài)

第三個(gè)參數(shù):持續(xù)監(jiān)聽(tīng)runloop狀態(tài)

第四個(gè)參數(shù):優(yōu)先級(jí)0

第五個(gè)參數(shù):activity runloop當(dāng)前的狀態(tài)

*/

CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities,YES,0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {

/*

kCFRunLoopEntry = (1UL << 0),進(jìn)入

kCFRunLoopBeforeTimers = (1UL << 1),即將處理timer事件

kCFRunLoopBeforeSources = (1UL << 2),將處理soure事件

kCFRunLoopBeforeWaiting = (1UL << 5),即將進(jìn)入休眠

kCFRunLoopAfterWaiting = (1UL << 6),被喚醒

kCFRunLoopExit = (1UL << 7),runloop退出

kCFRunLoopAllActivities = 0x0FFFFFFFU

*/

2.給對(duì)應(yīng)的runloop添加監(jiān)聽(tīng)者并且制定監(jiān)聽(tīng)的是哪種運(yùn)行模式

/*

第一個(gè)參數(shù):runloop對(duì)象本身

第二個(gè)參數(shù):監(jiān)聽(tīng)者(觀察者)

第三個(gè)參數(shù):runloop的運(yùn)行模式

*/

CFRunLoopAddObserver(CFRunLoopGetCurrent(),observer, kCFRunLoopDefaultMode);

4.Runloop應(yīng)用

1)NSTimer

2)ImageView顯示:控制方法在特定的模式下可用

3)PerformSelector

4)常駐線程:在子線程中開(kāi)啟一個(gè)runloop

5)自動(dòng)釋放池

第一次創(chuàng)建:進(jìn)入runloop的時(shí)候

最后一次釋放:runloop退出的時(shí)候

//其它創(chuàng)建和釋放:當(dāng)runloop即將休眠的時(shí)候會(huì)把之前的自動(dòng)釋放池釋放,然后重新創(chuàng)建一個(gè)新的釋放池//????

27.自定義轉(zhuǎn)場(chǎng)動(dòng)畫(huà):

1.在要跳轉(zhuǎn)的控制器實(shí)現(xiàn)系統(tǒng)跳轉(zhuǎn)

ZJViewController *zjVc = [[ZJViewController alloc] init];

[selfpresentViewController:zjVc animated:YEScompletion:nil];

2.給要跳轉(zhuǎn)的控制器設(shè)置代理為self,設(shè)置跳轉(zhuǎn)方式為UIModalPresentationCustom

zjVc.modalPresentationStyle = UIModalPresentationCustom;

zjVc.transitioningDelegate =self;

3.遵守UIViewControllerTransitioningDelegate協(xié)議,實(shí)現(xiàn)方法

- (nullableUIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source{

return[[UIPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];

}

4.需實(shí)現(xiàn)UIPresentationController里的方法,繼承自UIPresentationController寫(xiě)一個(gè)自己的跳轉(zhuǎn)控制器

//這里為ZJPresentationController

將第3步返回的對(duì)象改為這種類(lèi)型

return[[ZJPresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];

5.實(shí)現(xiàn)跳轉(zhuǎn)控制器(ZJPresentationController)的方法

- (void)containerViewWillLayoutSubviews{

//設(shè)置控制器的大小位置,不設(shè)置不會(huì)顯示出來(lái)

self.presentedView.frame =self.containerView.bounds;

}

- (void)presentationTransitionWillBegin{

[self.containerView addSubview:self.presentedView];

}

- (void)dismissalTransitionDidEnd:(BOOL)completed{

[self.presentedView removeFromSuperview];

}

6.設(shè)置動(dòng)畫(huà)的代理

只要遵守了UIViewControllerAnimatedTransitioning協(xié)議的都可以(復(fù)雜時(shí)新建一個(gè)對(duì)象專(zhuān)門(mén)管理動(dòng)畫(huà))

- (nullableid)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:

//返回控制器彈出時(shí)動(dòng)畫(huà)的代理

- (nullableid)animationControllerForDismissedController:(UIViewController *)dismissed

//返回控制器銷(xiāo)毀時(shí)動(dòng)畫(huà)的代理

7.代理中實(shí)現(xiàn)動(dòng)畫(huà)方法

- (void)animateTransition:(id)transitionContext

如果控制器彈出,銷(xiāo)毀都有動(dòng)畫(huà),則需聲明一個(gè)屬性來(lái)記錄彈出還是銷(xiāo)毀狀態(tài)

@property(nonatomic,assign)BOOLpresented;

并且在第6步中返回時(shí)給這個(gè)代理的presented屬性賦值(YES/NO)

然后根據(jù)這個(gè)屬性來(lái)做動(dòng)畫(huà)

[transitionContext viewForKey:UITransitionContextToViewKey];

//獲取彈出時(shí)的view

[transitionContext viewForKey:UITransitionContextFromViewKey]

//獲取銷(xiāo)毀時(shí)的view

[transitionContext completeTransition:YES];

//動(dòng)畫(huà)完成時(shí)一定要通知系統(tǒng)

假如要在首層disMiss掉需要通過(guò)創(chuàng)建手勢(shì)的方法

[self.presentedVC disMiss........]

攔截手勢(shì)的方法首先遵守手勢(shì)代理設(shè)置代理實(shí)現(xiàn)代理方法在代理方法中確定手勢(shì)的范圍.

cgpoint Point = [touch locationinView:手勢(shì)的View];

BOOLpresent = CGRectContainsPoint(self.presentedView.frame, point);

28.控制器的生命周期的方法以及調(diào)用的順序

//當(dāng)控制器View加載完畢時(shí)調(diào)用

- (void)viewDidLoad {

[superviewDidLoad];

NSLog(@"%s",__func__);

}

一般調(diào)用一次

//當(dāng)控制器View即將顯示時(shí)調(diào)用

- (void)viewWillAppear:(BOOL)animated {

[superviewWillAppear:animated];

NSLog(@"%s",__func__);

}

//當(dāng)控制器View顯示完畢時(shí)調(diào)用

- (void)viewDidAppear:(BOOL)animated {

[superviewDidAppear:animated];

NSLog(@"%s",__func__);

}

//當(dāng)控制器View即將布局子控件時(shí)調(diào)用

- (void)viewWillLayoutSubviews {

[superviewWillLayoutSubviews];

NSLog(@"%s",__func__);

}

//當(dāng)控制器View布局子控件完畢時(shí)調(diào)用

- (void)viewDidLayoutSubviews {

[superviewDidLayoutSubviews];

NSLog(@"%s",__func__);

}

//當(dāng)控制器View既將消失時(shí)調(diào)用

- (void)viewWillDisappear:(BOOL)animated {

[superviewWillDisappear:animated];

NSLog(@"%s",__func__);

}

//當(dāng)控制器View消失完畢時(shí)調(diào)用

- (void)viewDidDisappear:(BOOL)animated {

[superviewDidDisappear:animated];

NSLog(@"%s",__func__);

}

29.控制器的跳轉(zhuǎn)的方式以及數(shù)據(jù)傳遞的方式

1.手動(dòng)創(chuàng)建是由一個(gè)view跳轉(zhuǎn)到另外一個(gè)view;必須有標(biāo)識(shí)符的

2.用代碼根據(jù)標(biāo)識(shí)去跳轉(zhuǎn)

3.自動(dòng)創(chuàng)建是直接跳轉(zhuǎn)的點(diǎn)擊控件自動(dòng)轉(zhuǎn)到下一個(gè)控制器

4.數(shù)據(jù)傳遞的方式正向傳遞和逆向傳遞

5.正向傳遞

[[NSNotificationCenter defaultCenter]addObserver:selfselector:@selector(textChange) name:nilobject:self.accountTextF]

observer :

name:是通知的名字

object:是發(fā)通知的的人

selector :是方法

代理:

1.代理者:接收消息的人

2.被代理者:是發(fā)消息的人'

3.屬性:定義屬性@property(nonatimic,strong)id<協(xié)議名稱(chēng)>屬性名稱(chēng);

4.調(diào)用代理;

1.plist

1.1tmp:

1.2doucument

block的做法

//起別名

typedefvoid(^contanctBlock ) (XMGContactItem *);

//屬性

@property(nonatomic,copy)contanctBlock contactBlock;

調(diào)用block

if(self.contactBlock) {

self.contactBlock(item);

}

//在跳轉(zhuǎn)前之前會(huì)調(diào)用這個(gè)方法

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

XMGAddVC_3 *addVC = segue.destinationViewController;

addVC.contactBlock = ^(XMGContactItem *item){

//實(shí)現(xiàn)代碼

//2.1添加數(shù)據(jù)

[self.dataArray addObject:item];

//2.2刷新

[self.tableView reloadData];

};

}

30.UINavigationController(頂部導(dǎo)航條控制器)

1.代碼創(chuàng)建并設(shè)UINavigationController為window的跟控制器

在AppDelegate的didFinishLaunchingWithOptions方法中

1.創(chuàng)建window

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

2.創(chuàng)建UINavigationController并設(shè)置根控制器

UIViewController *vc = [[UIViewController alloc] init];

UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];

self.window.rootViewController = nav;

3.顯示window

[self.window makeKeyAndVisible];

//注意:需要將info.plist中的storyboard選項(xiàng)刪除

2.控制器之間的跳轉(zhuǎn)(先放的控制器在棧底,只能從頂部往下移除控制器)

1.push跳轉(zhuǎn)(往棧中放一個(gè)控制器)

UIViewController *vc = [UIViewController alloc] init];

[self.navigationController pushViewController:vc animated:YES];

2.pop跳轉(zhuǎn)

1.跳轉(zhuǎn)到上一個(gè)控制器(移除頂部的控制器)

[self.navigationController popViewControllerAnimated:YES];

2.跳轉(zhuǎn)到根控制器(移除根控制器以外所有控制器)

[self.navigationController popToRootViewControllerAnimated:YES];

3.跳轉(zhuǎn)到指定的控制器(移除指定控制器上面的控制器)

[self.navigationController popToViewController:self.navigationController.childViewControllers[0] animated:YES];

3.在storyboard中操作以上設(shè)置

1.創(chuàng)建UIViewController

1.拖一個(gè)UINavigationController視圖

2.拖一個(gè)UIViewController視圖

3.將UIViewController設(shè)置為UINavigationController視圖的rootViewController

按command+左鍵->拖線->選rootViewController

//注意:如果沒(méi)設(shè)置view顏色,會(huì)顯示為黑色

2.控制器的跳轉(zhuǎn)

1.自動(dòng)跳轉(zhuǎn)

從原控制器的控件(能監(jiān)聽(tīng)事件)中拖線到目標(biāo)控制器->選show//push已廢棄

2.手動(dòng)跳轉(zhuǎn)

從原控制器(上面的黃點(diǎn))中拖線到目標(biāo)控制器->選show//push已廢棄

//返回只能用代碼

//注意:在storyboard中線不能交叉

4.設(shè)置導(dǎo)航條的內(nèi)容(哪個(gè)的導(dǎo)航條由哪個(gè)控制器設(shè)置)(在storyboard中找相對(duì)應(yīng)屬性)

1.設(shè)置導(dǎo)航條標(biāo)題

self.navigationItem.title =@"標(biāo)題";

2.設(shè)置導(dǎo)航條視圖

self.navigationItem.titleView = [[UIView alloc]init];

3.設(shè)置導(dǎo)航條右邊視圖(左邊同理)

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"right"style:0target:selfaction:@selector(rightClick)];

4.在導(dǎo)航條中設(shè)置自定義的控件

UIButton *btn = [[UIButton alloc]init];

self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btn];

31.控制器之間數(shù)據(jù)傳遞

1.正向傳遞數(shù)據(jù)

在prepareForSegue方法中,先獲取跳轉(zhuǎn)時(shí)的segue,再獲得目標(biāo)控制器,再給目標(biāo)控制器的屬性賦值

//在storyboard中,不管是自動(dòng)跳轉(zhuǎn)還是手動(dòng)跳轉(zhuǎn),都會(huì)調(diào)用這個(gè)方法

//用代碼push不會(huì)調(diào)用

2.prepareForSegue底層實(shí)現(xiàn):

1.創(chuàng)建segue對(duì)象

2.將self賦值給segue的sourceViewController(源控制器)

3.創(chuàng)建目標(biāo)控制器,并賦值給segue的destinationViewController

4.傳遞參數(shù)

5.從源控制器push到目標(biāo)控制器

3.逆向傳遞數(shù)據(jù)

1.導(dǎo)入頭文件實(shí)現(xiàn)

//耦合性太強(qiáng)

2.使用代理

1.目標(biāo)控制器

1.聲明協(xié)議

2.聲明代理屬性(遵守協(xié)議)

3.調(diào)用代理方法//在返回上一層控制器前代用

2.源控制器

1.遵守協(xié)議

2.實(shí)現(xiàn)協(xié)議中的方法

3.設(shè)置self為目標(biāo)控制器代理//在prepareForSegue中

3.使用block

1.目標(biāo)控制器

1.聲明block屬性//一般使用typedef起別名

2.執(zhí)行block//傳遞參數(shù),在返回上層控制器之前執(zhí)行

2.源控制器

1.獲得目標(biāo)控制器//在prepareForSegue中

2.給目標(biāo)控制器的block賦值//即要執(zhí)行的代碼塊

4.通知

1.目標(biāo)控制器

發(fā)出通知到通知中心,并將數(shù)據(jù)打包成字典給userInfo//postNotification

2.源控制器

監(jiān)聽(tīng)通知//注意:在dealloc中要移除監(jiān)聽(tīng)

32.UITabBarController(底部導(dǎo)航條控制器)

1.代碼創(chuàng)建

1.創(chuàng)建window

self.window = [[UIWindow alloc]init];

2.創(chuàng)建UITabBarController

UITabBarController *tabVC =[[UITabBarController alloc] init];

3.添加子控件

UIViewController *vc1 = [[UIViewController alloc] init];

[tabVC addChildViewController:vc1];

//添加多少個(gè)子控制器,則底部導(dǎo)航條平分為多少份,并創(chuàng)建按鈕(默認(rèn)無(wú)文字無(wú)顏色)

UIViewController *vc2 = [[UIViewController alloc] init];

[tabVC addChildViewController:vc2];

4.顯示window

[self.window makeKeyAndVisible];

2.在storyboard中

1.拖一個(gè)UITabBarController視圖

2.拖子控制器UIViewController

3.從UITabBarController拖線到UIViewController,選view controllers

4.重復(fù)第3步,可添加多個(gè)子控制器

3.設(shè)置導(dǎo)航條內(nèi)容(哪個(gè)的導(dǎo)航條由哪個(gè)控制器設(shè)置)(在storyboard中找相對(duì)應(yīng)屬性)

1.設(shè)置顯示文字

self.tabBarItem.title =@"消息";

2.設(shè)置右上角紅色信息

self.tabBarItem.badgeValue =@"10";

3.設(shè)置顯示圖片

self.tabBarItem.image = [UIImage imageNamed:@"image"];

3.modal跳轉(zhuǎn)控制器

1.代碼跳轉(zhuǎn)

1.跳轉(zhuǎn)到指定控制器

UIViewController *vc = [UIViewController alloc] init];

[selfpresentViewController:vc animated:YEScompletion:^{ }];

2.返回上一層控制器

[selfdismissViewControllerAnimated:YEScompletion:^{ }];

2.在storyboard中

從源控制器(控件)拖線到目標(biāo)控制器->選Present Modally//modal已廢棄

//返回只能用代碼實(shí)現(xiàn)

33.dismissed的原理:它本身就是一個(gè)消息機(jī)制首先會(huì)判斷它有沒(méi)有彈出控制器,假如有的話調(diào)用dismiss就會(huì)銷(xiāo)毀彈出的控制假如沒(méi)有的話就會(huì)銷(xiāo)毀自己.

34.http:其0.9的版本和1.1的版本最大的區(qū)別是1.1可以持續(xù)鏈接他有兩個(gè)操作一個(gè)是請(qǐng)求還有一個(gè)就是響應(yīng)

35.get和post的區(qū)別

post發(fā)給服務(wù)器的參數(shù)放在請(qǐng)求體中其傳遞的數(shù)量沒(méi)有限制它的安全性比get高一般包含敏感信息的文件都用post文件傳輸

get一般它的url長(zhǎng)度不能超過(guò)1kb它傳輸?shù)臄?shù)據(jù)的大小一般都比較小

36.發(fā)送http請(qǐng)求的方案: nsurlConnection和nsurlsessioncfnetwork這三種

一般用第三方框架:AFNeWorking

37.將data轉(zhuǎn)為字符串[[NSString alloc]initWithData:date encoding:NSUTF8StringEncoding];這種方式可以

38.http的

NSURLConnection的get請(qǐng)求的方式已被棄用

/*

//路徑

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];

//請(qǐng)求對(duì)象

NSURLRequest *quest = [NSURLRequest requestWithURL:url];

//異步請(qǐng)求的方式

[NSURLConnectionsendAsynchronousRequest:quest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

NSLog(@"%@ ",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);

}];

//同步請(qǐng)求的方式

NSURLResponse *response = [[NSURLResponse alloc]init];

NSData *date= [ NSURLConnectionsendSynchronousRequest:quest returningResponse:&response error:nil];

NSLog(@"%@ ",[[NSString alloc]initWithData:date encoding:NSUTF8StringEncoding]);

//代理的方式

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];

//請(qǐng)求對(duì)象

NSURLRequest *quest = [NSURLRequest requestWithURL:url];

NSURLConnection *connect =[[NSURLConnectionalloc ]initWithRequest:quest delegate:self];

當(dāng)有startImmediately且為NO的時(shí)候就要自動(dòng)開(kāi)啟

[connect start];

*/

post的請(qǐng)求方式:

/*//1.確定請(qǐng)求路徑

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520&pwd=520it&type=JSON"];

//2.創(chuàng)建請(qǐng)求對(duì)象

NSURLRequest *request = [NSURLRequest requestWithURL:url];

//3.創(chuàng)建會(huì)話對(duì)象

NSURLSession *session = [NSURLSession sharedSession];

//4.創(chuàng)建task

第一個(gè)參數(shù):請(qǐng)求對(duì)象

第二個(gè)參數(shù):completionHandler完成(成功|失敗)后的回調(diào)

data:響應(yīng)體

response:響應(yīng)頭信息

error:錯(cuò)誤信息

//注意!!!completionHandler是在子線程中執(zhí)行的

NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

//6.解析數(shù)據(jù)

NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);

NSLog(@"%@",[NSThread currentThread]);

}];

//5.執(zhí)行Task

[dataTask resume];*/

39.downloadtask下載任務(wù):

1.傳入url

2.新建請(qǐng)求對(duì)象

這里要設(shè)置假如程序退出了,下載從上次的地方接著開(kāi)始下這時(shí)候就要用可變的請(qǐng)求去調(diào)用setValue的方法

3.創(chuàng)建session對(duì)象創(chuàng)建下載任務(wù)對(duì)象使用代理(遵守代理協(xié)議);

4.一定要resume恢復(fù)其操作;

調(diào)用方法: a.接受響應(yīng)獲取文件的總大小

新建一個(gè)輸出流對(duì)象調(diào)用打開(kāi)的方法用一個(gè)屬性去接收

b.接收數(shù)據(jù)可以拿到當(dāng)前的傳輸數(shù)據(jù)的大小總共傳輸了大小用一個(gè)屬性去保存每次傳輸?shù)拇笮≡倜看渭由厦看蝹鬏數(shù)臄?shù)據(jù)的大小設(shè)置存儲(chǔ)路徑將數(shù)據(jù)一點(diǎn)點(diǎn)的加進(jìn)磁盤(pán)內(nèi)用輸出流對(duì)象調(diào)用將數(shù)據(jù)寫(xiě)入磁盤(pán)內(nèi)

并在這里調(diào)用刷新UI的方法在主線程中

c.任務(wù)完成或者請(qǐng)求出錯(cuò)

將輸出流對(duì)象調(diào)用關(guān)閉的方法并將輸出流對(duì)象設(shè)置成nil

[[NSFileManager defaultManager]moveItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:nil];本地文件的寫(xiě)入移動(dòng).

40.AFNetWorking的應(yīng)用;

發(fā)送請(qǐng)求: get請(qǐng)求創(chuàng)建一個(gè)會(huì)話創(chuàng)建一個(gè)字典調(diào)用get方法

//NSString *url = @"http://120.25.226.186:32812/login";

AFHTTPSessionManager *http = [AFHTTPSessionManager manager];

NSDictionary *dic =@{

@"username":@"520it",

@"pwd":@"520it",

};

[http GET:@"http://120.25.226.186:32812/login"parameters:dic progress:nilsuccess:^(NSURLSessionDataTask *_Nonnulltask,id_NullableresponseObject) {

NSLog(@"請(qǐng)求成功");

NSLog(@"%@ ------%@",[responseObject class],responseObject);

} failure:^(NSURLSessionDataTask *_Nullabletask, NSError *_Nonnullerror) {

NSLog(@"請(qǐng)求失敗");

}];

post請(qǐng)求創(chuàng)建一個(gè)會(huì)話創(chuàng)建一個(gè)字典調(diào)用post方法跟get方法一樣;

2.文件上傳upload

//1.創(chuàng)建會(huì)話管理者

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//2.發(fā)送請(qǐng)求上傳文件

/*

第一個(gè)參數(shù):請(qǐng)求路徑(NSString)

第二個(gè)參數(shù):非文件參數(shù)

第三個(gè)參數(shù):constructingBodyWithBlock拼接數(shù)據(jù)(告訴AFN要上傳的數(shù)據(jù)是哪些)

第四個(gè)參數(shù):progress進(jìn)度回調(diào)

第五個(gè)參數(shù):success成功回調(diào)

responseObject:響應(yīng)體

第六個(gè)參數(shù):failure失敗的回調(diào)

*/

[manager POST:@"http://120.25.226.186:32812/upload"parameters:nilconstructingBodyWithBlock:^(id_NonnullformData) {

//拼接數(shù)據(jù)

/*

第一個(gè)參數(shù):文件的路徑(NSURL)

第二個(gè)參數(shù):參數(shù)名~file

第三個(gè)參數(shù):該文件上傳到服務(wù)器以什么名稱(chēng)來(lái)保存

第四個(gè)參數(shù):文件的二進(jìn)制數(shù)據(jù)類(lèi)型

*/

NSURL *url = [NSURL fileURLWithPath:@"/Users/apple/Desktop/Snip20160409_148.png"];

//[formData appendPartWithFileURL:url name:@"file" fileName:@"abc.png" mimeType:@"image/png" error:nil];

[formData appendPartWithFileURL:url name:@"file"error:nil];

} progress:^(NSProgress *_NonnulluploadProgress) {

NSLog(@"%f",1.0* uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);

} success:^(NSURLSessionDataTask *_Nonnulltask,id_NullableresponseObject) {

NSLog(@"success--%@",responseObject);

} failure:^(NSURLSessionDataTask *_Nullabletask, NSError *_Nonnullerror) {

NSLog(@"failure -- %@",error);

}];

41.加密過(guò)程:機(jī)密的一些最基本的操作

NSString *key =@"abc";

NSString *string =@"520it";

//AES - ECB加密

/*

第一個(gè)參數(shù):要加密的明文(字符串)

第二個(gè)參數(shù):共享密鑰

第三個(gè)參數(shù):nil (初始向量)

*/

NSLog(@"AES - ECB加密:%@",[[EncryptionTools sharedEncryptionTools] encryptString:string keyString:key iv:nil]);

//FqRpCOQG9IL2QrKBHhM+fA==

NSLog(@"AES - ECB解密:%@",[[EncryptionTools sharedEncryptionTools] decryptString:@"FqRpCOQG9IL2QrKBHhM+fA=="keyString:key iv:nil]);

//AES -CBC

uint8_t iv[8] ={1,2,3,4,5,6,7,8};

NSData *data = [NSData dataWithBytes:iv length:sizeof(iv)];

NSLog(@"AES - CBC加密:%@",[[EncryptionTools sharedEncryptionTools] encryptString:string keyString:key iv:data]);

//$ echo -n "520it" |openssl enc -aes-128-cbc -K 616263 -nosalt -iv 0102030405060708 |base64

NSLog(@"AES - CBC解密:%@",[[EncryptionTools sharedEncryptionTools] decryptString:@"Kd9MN/rNEI40hdLhayPbUw=="keyString:key iv:data]);

//DES - ECB

//1.需要修改加密方式為kCCAlgorithmDES

[EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;

NSLog(@"DES - ECB加密:%@",[[EncryptionTools sharedEncryptionTools] encryptString:string keyString:key iv:nil]);

NSLog(@"DES - ECB解密:%@",[[EncryptionTools sharedEncryptionTools] decryptString:@"VqYjXo2ZlU4="keyString:key iv:nil]);

42.基礎(chǔ)動(dòng)畫(huà)和核心動(dòng)畫(huà)

CAPropertyAnimation

是CAAnimation的子類(lèi)斥黑,也是個(gè)抽象類(lèi)揖盘,要想創(chuàng)建動(dòng)畫(huà)對(duì)象,應(yīng)該使用它的兩個(gè)子類(lèi):CABasicAnimation和CAKeyframeAnimation

屬性解析:

keyPath:通過(guò)指定CALayer的一個(gè)屬性名稱(chēng)為keyPath(NSString類(lèi)型)锌奴,并且對(duì)CALayer的這個(gè)屬性的值進(jìn)行修改兽狭,達(dá)到相應(yīng)的動(dòng)畫(huà)效果。比如鹿蜀,指定@”position”為keyPath箕慧,就修改CALayer的position屬性的值,以達(dá)到平移的動(dòng)畫(huà)效果

屬性解析:(紅色代表來(lái)自CAMediaTiming協(xié)議的屬性)

duration:動(dòng)畫(huà)的持續(xù)時(shí)間

repeatCount:動(dòng)畫(huà)的重復(fù)次數(shù)

repeatDuration:動(dòng)畫(huà)的重復(fù)時(shí)間

removedOnCompletion:默認(rèn)為YES茴恰,代表動(dòng)畫(huà)執(zhí)行完畢后就從圖層上移除颠焦,圖形會(huì)恢復(fù)到動(dòng)畫(huà)執(zhí)行前的狀態(tài)。如果想讓圖層保持顯示動(dòng)畫(huà)執(zhí)行后的狀態(tài)往枣,那就設(shè)置為NO伐庭,不過(guò)還要設(shè)置fillMode為kCAFillModeForwards

fillMode:決定當(dāng)前對(duì)象在非active時(shí)間段的行為.比如動(dòng)畫(huà)開(kāi)始之前,動(dòng)畫(huà)結(jié)束之后

beginTime:可以用來(lái)設(shè)置動(dòng)畫(huà)延遲執(zhí)行時(shí)間,若想延遲2s分冈,就設(shè)置為CACurrentMediaTime()+2圾另,CACurrentMediaTime()為圖層的當(dāng)前時(shí)間

timingFunction:速度控制函數(shù),控制動(dòng)畫(huà)運(yùn)行的節(jié)奏

delegate:動(dòng)畫(huà)代理

fromValue:keyPath相應(yīng)屬性的初始值

toValue:keyPath相應(yīng)屬性的結(jié)束值

隨著動(dòng)畫(huà)的進(jìn)行雕沉,在長(zhǎng)度為duration的持續(xù)時(shí)間內(nèi)集乔,keyPath相應(yīng)屬性的值從fromValue漸漸地變?yōu)閠oValue

如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在動(dòng)畫(huà)執(zhí)行完畢后蘑秽,圖層會(huì)保持顯示動(dòng)畫(huà)執(zhí)行后的狀態(tài)饺著。但在實(shí)質(zhì)上箫攀,圖層的屬性值還是動(dòng)畫(huà)執(zhí)行前的初始值,并沒(méi)有真正被改變幼衰。比如靴跛,CALayer的position初始值為(0,0),CABasicAnimation的fromValue為(10,10)渡嚣,toValue為(100,100)梢睛,雖然動(dòng)畫(huà)執(zhí)行完畢后圖層保持在(100,100)這個(gè)位置,實(shí)質(zhì)上圖層的position還是為(0,0)

CAKeyframeAnimation是CApropertyAnimation的子類(lèi)识椰,跟CABasicAnimation的區(qū)別是:CABasicAnimation只能從一個(gè)數(shù)值(fromValue)變到另一個(gè)數(shù)值(toValue)绝葡,而CAKeyframeAnimation會(huì)使用一個(gè)NSArray保存這些數(shù)值

屬性解析:

values:就是上述的NSArray對(duì)象。里面的元素稱(chēng)為”關(guān)鍵幀”(keyframe)腹鹉。動(dòng)畫(huà)對(duì)象會(huì)在指定的時(shí)間(duration)內(nèi)藏畅,依次顯示values數(shù)組中的每一個(gè)關(guān)鍵幀

path:可以設(shè)置一個(gè)CGPathRef\CGMutablePathRef,讓層跟著路徑移動(dòng)。path只對(duì)CALayer的anchorPoint和position起作用功咒。如果你設(shè)置了path愉阎,那么values將被忽略

keyTimes:可以為對(duì)應(yīng)的關(guān)鍵幀指定對(duì)應(yīng)的時(shí)間點(diǎn),其取值范圍為0到1.0,keyTimes中的每一個(gè)時(shí)間值都對(duì)應(yīng)values中的每一幀.當(dāng)keyTimes沒(méi)有設(shè)置的時(shí)候,各個(gè)關(guān)鍵幀的時(shí)間是平分的

CABasicAnimation可看做是最多只有2個(gè)關(guān)鍵幀的CAKeyframeAnimation

運(yùn)用:

CAAnimationGroup

CAAnimation的子類(lèi),可以保存一組動(dòng)畫(huà)對(duì)象力奋,將CAAnimationGroup對(duì)象加入層后榜旦,組中所有動(dòng)畫(huà)對(duì)象可以同時(shí)并發(fā)運(yùn)行

animations:用來(lái)保存一組動(dòng)畫(huà)對(duì)象的NSArray

默認(rèn)情況下,一組動(dòng)畫(huà)對(duì)象是同時(shí)運(yùn)行的景殷,也可以通過(guò)設(shè)置動(dòng)畫(huà)對(duì)象的beginTime屬性來(lái)更改動(dòng)畫(huà)的開(kāi)始時(shí)間

組動(dòng)畫(huà)

CATransition是CAAnimation的子類(lèi)溅呢,用于做轉(zhuǎn)場(chǎng)動(dòng)畫(huà),能夠?yàn)閷犹峁┮瞥銎聊缓鸵迫肫聊坏膭?dòng)畫(huà)效果猿挚。iOS比Mac OS X的轉(zhuǎn)場(chǎng)動(dòng)畫(huà)效果少一點(diǎn)

UINavigationController就是通過(guò)CATransition實(shí)現(xiàn)了將控制器的視圖推入屏幕的動(dòng)畫(huà)效果

type:動(dòng)畫(huà)過(guò)渡類(lèi)型

subtype:動(dòng)畫(huà)過(guò)渡方向

startProgress:動(dòng)畫(huà)起點(diǎn)(在整體動(dòng)畫(huà)的百分比)

endProgress:動(dòng)畫(huà)終點(diǎn)(在整體動(dòng)畫(huà)的百分比)

轉(zhuǎn)場(chǎng)動(dòng)畫(huà)過(guò)渡效果

運(yùn)用:

雨滴效果

補(bǔ)充:

一:CAAnimation——?jiǎng)赢?huà)代理方法

1.CAAnimation在分類(lèi)中定義了代理方法,是給NSObject添加的分類(lèi),所以任何對(duì)象,成為CAAnimation的代理都可以

@interfaceNSObject (CAAnimationDelegate)

/* Called when the animation begins its active duration. */

動(dòng)畫(huà)開(kāi)始的時(shí)候調(diào)用:-(void)animationDidStart:(CAAnimation*)anim;

動(dòng)畫(huà)停止的時(shí)候調(diào)用:-(void)animationDidStop:(CAAnimation*)anim finished:(BOOL)flag;

@end

二:CALayer上動(dòng)畫(huà)的暫停和恢復(fù)

pragma mark暫停CALayer的動(dòng)畫(huà)

-(void)pauseLayer:(CALayer*)layer

{

CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];

讓CALayer的時(shí)間停止走動(dòng):layer.speed =0.0;

讓CALayer的時(shí)間停留在pausedTime這個(gè)時(shí)刻:layer.timeOffset = pausedTime;

}

三:CALayer上動(dòng)畫(huà)的恢復(fù)

pragma mark恢復(fù)CALayer的動(dòng)畫(huà)

-(void)resumeLayer:(CALayer*)layer

{

CFTimeInterval pausedTime = layer.timeOffset;

1.讓CALayer的時(shí)間繼續(xù)行走:layer.speed =1.0;

2.取消上次記錄的停留時(shí)刻:layer.timeOffset =0.0;

3.取消上次設(shè)置的時(shí)間:layer.beginTime =0.0;

4.計(jì)算暫停的時(shí)間(這里也可以用CACurrentMediaTime()-pausedTime)

CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime()fromLayer:nil] - pausedTime;

5.設(shè)置相對(duì)于父坐標(biāo)系的開(kāi)始時(shí)間(往后退timeSincePause):layer.beginTime = timeSincePause;

}

二咐旧、UIView動(dòng)畫(huà)

UIKit直接將動(dòng)畫(huà)集成到UIView類(lèi)中,當(dāng)內(nèi)部的一些屬性發(fā)生改變時(shí)亭饵,UIView將為這些改變提供動(dòng)畫(huà)支持

執(zhí)行動(dòng)畫(huà)所需要的工作由UIView類(lèi)自動(dòng)完成休偶,但仍要在希望執(zhí)行動(dòng)畫(huà)時(shí)通知視圖,為此需要將改變屬性的代碼放在[UIView beginAnimations:nilcontext:nil]和[UIView commitAnimations]之間

常見(jiàn)方法解析:

+ (void)setAnimationDelegate:(id)delegate

設(shè)置動(dòng)畫(huà)代理對(duì)象辜羊,當(dāng)動(dòng)畫(huà)開(kāi)始或者結(jié)束時(shí)會(huì)發(fā)消息給代理對(duì)象

+ (void)setAnimationWillStartSelector:(SEL)selector

當(dāng)動(dòng)畫(huà)即將開(kāi)始時(shí)踏兜,執(zhí)行delegate對(duì)象的selector,并且把beginAnimations:context:中傳入的參數(shù)傳進(jìn)selector

+ (void)setAnimationDidStopSelector:(SEL)selector

當(dāng)動(dòng)畫(huà)結(jié)束時(shí)八秃,執(zhí)行delegate對(duì)象的selector碱妆,并且把beginAnimations:context:中傳入的參數(shù)傳進(jìn)selector

+ (void)setAnimationDuration:(NSTimeInterval)duration

動(dòng)畫(huà)的持續(xù)時(shí)間,秒為單位

+ (void)setAnimationDelay:(NSTimeInterval)delay

動(dòng)畫(huà)延遲delay秒后再開(kāi)始

+ (void)setAnimationStartDate:(NSDate *)startDate

動(dòng)畫(huà)的開(kāi)始時(shí)間昔驱,默認(rèn)為now

+ (void)setAnimationCurve:(UIViewAnimationCurve)curve

動(dòng)畫(huà)的節(jié)奏控制,具體看下面的”備注”

+ (void)setAnimationRepeatCount:(float)repeatCount

動(dòng)畫(huà)的重復(fù)次數(shù)

+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses

如果設(shè)置為YES,代表動(dòng)畫(huà)每次重復(fù)執(zhí)行的效果會(huì)跟上一次相反

+ (void)setAnimationTransition:(UIViewAnimationTransition)transition

forView:(UIView *)view cache:(BOOL)cache

設(shè)置視圖view的過(guò)渡效果, transition指定過(guò)渡類(lèi)型, cache設(shè)置YES代表使用視圖緩存疹尾,性能較好

三、Block動(dòng)畫(huà)

Block

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOLfinished))completion

###參數(shù)解析:

duration:動(dòng)畫(huà)的持續(xù)時(shí)間

delay:動(dòng)畫(huà)延遲delay秒后開(kāi)始

options:動(dòng)畫(huà)的節(jié)奏控制

animations:將改變視圖屬性的代碼放在這個(gè)block中

completion:動(dòng)畫(huà)結(jié)束后,會(huì)自動(dòng)調(diào)用這個(gè)block

+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void(^)(void))animations completion:(void(^)(BOOLfinished))completion

###參數(shù)解析:

duration:動(dòng)畫(huà)的持續(xù)時(shí)間

view:需要進(jìn)行轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的視圖

options:轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的類(lèi)型

animations:將改變視圖屬性的代碼放在這個(gè)block中

completion:動(dòng)畫(huà)結(jié)束后纳本,會(huì)自動(dòng)調(diào)用這個(gè)block

+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void(^)(BOOLfinished))completion

###方法調(diào)用完畢后窍蓝,相當(dāng)于執(zhí)行了下面兩句代碼:

//添加toView到父視圖

[fromView.superview addSubview:toView];

//把fromView從父視圖中移除

[fromView.superview removeFromSuperview];

###參數(shù)解析:

duration:動(dòng)畫(huà)的持續(xù)時(shí)間

options:轉(zhuǎn)場(chǎng)動(dòng)畫(huà)的類(lèi)型

animations:將改變視圖屬性的代碼放在這個(gè)block中

completion:動(dòng)畫(huà)UIImageView的幀動(dòng)畫(huà)后,會(huì)自動(dòng)調(diào)用這個(gè)block

UIImageView的幀動(dòng)畫(huà)

UIImageView可以讓一系列的圖片在特定的時(shí)間內(nèi)按順序顯示

###相關(guān)屬性解析:

animationImages:要顯示的圖片(一個(gè)裝著UIImage的NSArray)

animationDuration:完整地顯示一次animationImages中的所有圖片所需的時(shí)間

animationRepeatCount:動(dòng)畫(huà)的執(zhí)行次數(shù)(默認(rèn)為0繁成,代表無(wú)限循環(huán))

###相關(guān)方法解析:

-(void)startAnimating;開(kāi)始動(dòng)畫(huà)

-(void)stopAnimating;停止動(dòng)畫(huà)

-(BOOL)isAnimating;是否正在運(yùn)行動(dòng)畫(huà)

UIActivityIndicatorView

###是一個(gè)旋轉(zhuǎn)進(jìn)度輪吓笙,可以用來(lái)告知用戶有一個(gè)操作正在進(jìn)行中,一般用initWithActivityIndicatorStyle初始化

###UIActivityIndicatorViewStyle有3個(gè)值可供選擇:

UIActivityIndicatorViewStyleWhiteLarge//大型白色指示器

UIActivityIndicatorViewStyleWhite//標(biāo)準(zhǔn)尺寸白色指示器

UIActivityIndicatorViewStyleGray//灰色指示器巾腕,用于白色背景

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末面睛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子尊搬,更是在濱河造成了極大的恐慌叁鉴,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佛寿,死亡現(xiàn)場(chǎng)離奇詭異幌墓,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)狗准,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)克锣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)茵肃,“玉大人腔长,你說(shuō)我怎么就攤上這事⊙椴校” “怎么了捞附?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)您没。 經(jīng)常有香客問(wèn)我鸟召,道長(zhǎng),這世上最難降的妖魔是什么氨鹏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任欧募,我火速辦了婚禮,結(jié)果婚禮上仆抵,老公的妹妹穿的比我還像新娘跟继。我一直安慰自己,他們只是感情好镣丑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布舔糖。 她就那樣靜靜地躺著,像睡著了一般莺匠。 火紅的嫁衣襯著肌膚如雪金吗。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音摇庙,去河邊找鬼旱物。 笑死,一個(gè)胖子當(dāng)著我的面吹牛卫袒,可吹牛的內(nèi)容都是我干的异袄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼玛臂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼烤蜕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起迹冤,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤讽营,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后泡徙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體橱鹏,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年堪藐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了莉兰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡糖荒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出模捂,到底是詐尸還是另有隱情捶朵,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布狂男,位于F島的核電站综看,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏岖食。R本人自食惡果不足惜红碑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泡垃。 院中可真熱鬧析珊,春花似錦、人聲如沸兔毙。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)澎剥。三九已至锡溯,卻和暖如春赶舆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背祭饭。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工芜茵, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人倡蝙。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓九串,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親寺鸥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子猪钮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 原文鏈接http://www.cnblogs.com/kenshincui/p/4186022.html 音頻在i...
    Hyman0819閱讀 21,708評(píng)論 4 74
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫(huà)效果腻要,實(shí)現(xiàn)這些動(dòng)畫(huà)的過(guò)程并不復(fù)雜,今天將帶大家一窺iOS動(dòng)畫(huà)全貌涝登。在這里你可以看...
    F麥子閱讀 5,113評(píng)論 5 13
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫(huà)效果雄家,實(shí)現(xiàn)這些動(dòng)畫(huà)的過(guò)程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫(huà)全貌缀拭。在這里你可以看...
    每天刷兩次牙閱讀 8,495評(píng)論 6 30
  • 童年是樹(shù)上的蟬咳短,水里的蛙,童年是牧童的短笛蛛淋,是伙伴的迷藏。
    很難忘記的密碼閱讀 489評(píng)論 0 0
  • 是什么??是控件,繼承UIView!有什么作用??能夠?qū)崿F(xiàn)滾動(dòng),縮放功能! 滾動(dòng)常用屬性?contentSize:...
    js_huh閱讀 220評(píng)論 0 0