国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

免費(fèi)網(wǎng)站注冊(cè)永久2345網(wǎng)址導(dǎo)航電腦版

免費(fèi)網(wǎng)站注冊(cè)永久,2345網(wǎng)址導(dǎo)航電腦版,貴州省中海工程建設(shè)有限公司網(wǎng)站,塑膠原料 東莞網(wǎng)站建設(shè)iOS 需要在info.plist中 添加的權(quán)限 1 概述 UIKit 框架提供了 iOS 或 Apple tvOS App 所需的基礎(chǔ)架構(gòu)。它提供了用于實(shí)施界面的窗口和視圖架構(gòu),用于向 App 提供多點(diǎn)觸控和其他類型輸入的事件處理基礎(chǔ)架構(gòu),以及管理用戶、系統(tǒng)和 App 之間互動(dòng)所需的主運(yùn)行…

iOS 需要在info.plist中 添加的權(quán)限

1 概述

UIKit 框架提供了 iOS 或 Apple tvOS App 所需的基礎(chǔ)架構(gòu)。它提供了用于實(shí)施界面的窗口和視圖架構(gòu),用于向 App 提供多點(diǎn)觸控和其他類型輸入的事件處理基礎(chǔ)架構(gòu),以及管理用戶、系統(tǒng)和 App 之間互動(dòng)所需的主運(yùn)行循環(huán)。該框架提供的其他功能包括動(dòng)畫(huà)支持、文檔支持、繪圖和打印支持、當(dāng)前設(shè)備的相關(guān)信息、文本管理和顯示、搜索支持、輔助功能支持、App 擴(kuò)展支持和資源管理。

// 框架的入口#import <UIKit/UIKit.h> 

UIKit是Cocoa Touch的一部分,提供了一組類來(lái)創(chuàng)建和管理iOS App的窗口和視圖、處理事件、繪圖和動(dòng)畫(huà)等,框架中的類具有如下繼承關(guān)系結(jié)構(gòu)

常用的UIKit組件有

·UIView及子類,包括UIScrollView(UITableView、UICollectionView、UITextView)、UILabel、UIControl(UIButton、UITextField)、UIPickerView等;

·與控件相關(guān)但不能被人所直觀看到的圖形、繪圖、打印、文本等的配置與控制,包括UIViewController、UIImage等。

1.1 界面構(gòu)建

·xib:輕量級(jí)的,可通過(guò)拖拽進(jìn)行界面創(chuàng)作和布局,本質(zhì)是個(gè)XML文件。

·nib(NeXT Interface Builder):xib編譯后得到的二進(jìn)制文件。

·storyboard:重量級(jí)的,自iOS 5引入,用來(lái)描述整個(gè)軟件的多個(gè)界面,也是個(gè)XML文件。

storyboard使用方式:

·通過(guò)拖放對(duì)象來(lái)完成靜態(tài)的界面布局,通過(guò)連線把靜態(tài)的元素與代碼進(jìn)行關(guān)聯(lián),如IBOutlet和IBAction。

storyboard優(yōu)缺點(diǎn):

·它可以用于描述不同視圖之間的關(guān)聯(lián),具有原型表項(xiàng)(prototype cell)和靜態(tài)表項(xiàng)(static cell)特性和簡(jiǎn)化自動(dòng)布局等特點(diǎn);

·性能較差,容易發(fā)生沖突,不便于進(jìn)行模塊化管理。

1.2 生命周期

UIApplication對(duì)象是應(yīng)用程序的象征,一個(gè) UIApplication 對(duì)象就代表一個(gè)應(yīng)用程序。一個(gè) iOS 程序啟動(dòng)后創(chuàng)建的第一個(gè)對(duì)象就是 UIApplication 對(duì)象。利用 UIApplication 對(duì)象,能進(jìn)行一些應(yīng)用級(jí)別的操作。每個(gè)iOS APP都只有一個(gè)UIApplication(或者很少有的UIApplication子類)實(shí)例。當(dāng)應(yīng)用程序啟動(dòng)時(shí),系統(tǒng)會(huì)調(diào)用UIApplicationMain(_:_:_:_:)函數(shù)。每一個(gè)應(yīng)用都有自己的單例的UIApplication 對(duì)象,如果試圖在程序中新建一個(gè)UIApplication對(duì)象,那么將報(bào)錯(cuò)。

The Main Run Loop主運(yùn)行循環(huán)負(fù)責(zé)處理用戶相關(guān)的事件。UIApplication對(duì)象在程序啟動(dòng)時(shí)啟動(dòng)Main Run Loop,它處理事件和更新視圖的界面,它是運(yùn)行在程序的主線程上的,這樣保證了接收到用戶相關(guān)操作的事件是按順序處理的。UIApplication對(duì)象處理傳入用戶事件的初始路由,它將UIControl類對(duì)象轉(zhuǎn)發(fā)給它的動(dòng)作消息分派給適當(dāng)?shù)哪繕?biāo)對(duì)象。UIApplication對(duì)象維護(hù)一個(gè)打開(kāi)的窗口(UIWindow對(duì)象)列表,它可以用來(lái)檢索任何應(yīng)用程序的UIView對(duì)象。

UIApplication對(duì)象會(huì)被賦予一個(gè)代理對(duì)象,以處理應(yīng)用程序的生命周期事件(比如程序啟動(dòng)和關(guān)閉)。在移動(dòng)操作系統(tǒng)中,應(yīng)用程序很容易受到來(lái)電、鎖屏等干擾,這時(shí)UIApplication對(duì)象也會(huì)通知它的代理對(duì)象,讓代理對(duì)象來(lái)處理這些系統(tǒng)事件。

UIApplication狀態(tài):1)Not running(未運(yùn)行)程序沒(méi)啟動(dòng);2)Inactive(未激活)程序在前臺(tái)運(yùn)行沒(méi)有接收到事件;3)Active(激活)程序在前臺(tái)運(yùn)行而且接收到了事件;4)Background(后臺(tái)) 程序在后臺(tái)而且能執(zhí)行代碼,執(zhí)行完畢或超時(shí)后會(huì)進(jìn)入掛起狀態(tài) (Suspended),有的程序經(jīng)過(guò)特殊的請(qǐng)求后可以長(zhǎng)期處于 Background 狀態(tài);5)Suspended(掛起)程序在后臺(tái)不能執(zhí)行代碼。系統(tǒng)會(huì)自動(dòng)把程序變成這個(gè)狀態(tài)而且不會(huì)發(fā)出通知。當(dāng)掛起時(shí),程序還是停留在內(nèi)存中的,當(dāng)系統(tǒng)內(nèi)存低時(shí),系統(tǒng)就把掛起的程序清除掉,為前臺(tái)程序提供更多的內(nèi)存。

UIApplication詳細(xì)介紹: Apple Developer Documentation iOS應(yīng)用程序生命周期(前后臺(tái)切換,應(yīng)用的各種狀態(tài))詳解_空杯子_的博客-CSDN博客

懶加載的優(yōu)勢(shì)

懶加載(延遲加載),把對(duì)象的實(shí)例化盡量延遲,即啟動(dòng)應(yīng)用程序時(shí)不加載這個(gè)資源,只有在運(yùn)行時(shí)用到才加載(按需加載。

例如,如果啟動(dòng)APP后一次性加載大量數(shù)據(jù)、圖片和音視頻等資源,就有可能會(huì)耗盡移動(dòng)設(shè)備內(nèi)存。這時(shí)就可以使用懶加載技術(shù)。具體來(lái)說(shuō),重寫(xiě)屬性的getter方法,先判斷該屬性是否為nil,如果為空再進(jìn)行實(shí)例化,否則直接返回屬性。

懶加載的好處有:不必將創(chuàng)建對(duì)象的代碼全部寫(xiě)在viewDidLoad方法中,代碼的可讀性更強(qiáng);每個(gè)控件分別負(fù)責(zé)各自的實(shí)例化處理,代碼的耦合程度低;不必在初始化階段加載所有數(shù)據(jù),節(jié)省內(nèi)存,也就是系統(tǒng)的內(nèi)存占用率會(huì)減少;減少服務(wù)器端壓力。

1.2.1 UIApplication

·UIApplicationMain

int main(int argc, char * argv[]) {NSString * appDelegateClassName;appDelegateClassName = NSStringFromClass([AppDelegate class]);/*** 前兩個(gè)參數(shù)和C語(yǔ)言一致* 第三個(gè)參數(shù)是NSString *principalClassName,如果是nil,那么它的值將從Info.plist獲取,如果Info.plist沒(méi)有,則默認(rèn)為 UIApplication。principalClass這個(gè)類除了管理整個(gè)程序的生命周期之外什么都不做,它只負(fù)責(zé)監(jiān)聽(tīng)事件然后交給delegateClass處理。* 第四個(gè)參數(shù)是NSString *delegateClassName,作用是對(duì)一系列系統(tǒng)事件,如程序?qū)⒁獑?dòng)、程序啟動(dòng)完成、程序進(jìn)入后臺(tái)、程序進(jìn)入前臺(tái)、程序退出等做出反應(yīng)。AppDelegate是UIApplication默認(rèn)的代理,已經(jīng)遵守了UIApplicationDelegate協(xié)議。**/return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

·APP的生命周期:

·didFinishLaunchingWithOptions

在這個(gè)函數(shù)中可以用如下類似的代碼創(chuàng)建一個(gè)UIWindow:

// 偽代碼:self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]

如果在指定模版時(shí)選擇了storyboard,那么Info.plist的Main storyboard file name(UIMainStoryboardFile)會(huì)指向主storyboard。UIApplicationMain實(shí)例化代理后,會(huì)向代理詢問(wèn)其window屬性的值;如果該值為 nil,則創(chuàng)建UIWindow對(duì)象并將其指定給代理的window屬性,然后將主storyboard的初始視圖控制器實(shí)例化并分配給窗口的rootViewController屬性,結(jié)果是將其作為根視圖控制器放置在窗口中,再向窗口發(fā)送makeKeyAndVisible消息。

1.2.2 視圖控制器

每個(gè)視圖控制器VC都維護(hù)一個(gè)視圖層次,視圖層次的根結(jié)點(diǎn)是根視圖,可以通過(guò)self.view來(lái)訪問(wèn),每個(gè)視圖都有自己的子視圖。

調(diào)用時(shí)機(jī)

方法

作用

默認(rèn)實(shí)現(xiàn)

UIStoryboard獲取視圖控制器,或者NSBundle加載nib文件時(shí)

- (instancetype)initWithCoder:(NSCoder *)coder

nib文件、xib或storyboard中加載視圖控制器

在當(dāng)前所有控件元素都加載好之后

awakeFromNib

該消息發(fā)送給所有擁有已加載元素的對(duì)象,表明對(duì)其他加載對(duì)象的所有引用都是有效且可用的。

VC在view屬性被請(qǐng)求且當(dāng)前view為nil時(shí)

loadView

VC在初始化時(shí)創(chuàng)建一個(gè)UIView對(duì)象,作為默認(rèn)視圖,可以通過(guò)self.view來(lái)訪問(wèn)。

從Storyboard或xib中加載VC的視圖設(shè)為當(dāng)前VC的視圖屬性,如果沒(méi)有關(guān)聯(lián)的文件則創(chuàng)建一個(gè)空白視圖給VC的視圖屬性。

視圖層次已經(jīng)放入內(nèi)存中。在控制器因?yàn)槟撤N原因如要顯示,需要使用到該視圖的時(shí)候調(diào)用。一個(gè)VC生命周期內(nèi)只會(huì)調(diào)用一次。

-(void)viewDidLoad

可以在此完成自定義數(shù)據(jù)和控件;當(dāng)幾何內(nèi)容被確定之后,viewWillLayoutSubview和viewDidLayoutSubviews被調(diào)用

視圖的基本的初始化,除了幾何圖形的初始化

當(dāng)收到視圖在窗口將可見(jiàn)時(shí)??赡軙?huì)調(diào)用多次。

-(void)viewWillAppear:(BOOL)animated:

對(duì)不可見(jiàn)時(shí)可能改變的數(shù)據(jù)進(jìn)行同步

不執(zhí)行任何操作

當(dāng)收到視圖在窗口已可見(jiàn)時(shí),此時(shí)視圖已在屏幕上渲染完成

-(void)viewDidAppear:(BOOL)animated:

不執(zhí)行任何操作

視圖被駁回時(shí)。當(dāng)收到視圖將去除、被覆蓋或隱藏于窗口的通知時(shí)。

-(void)viewWillDisappear:(BOOL)animated:

不執(zhí)行任何操作

視圖被駁回后。當(dāng)收到視圖已去除、被覆蓋或隱藏于窗口的通知時(shí)。

-(void)viewDidDisappear:(BOOL)animated

不執(zhí)行任何操作

返回是否支持不同方向的旋轉(zhuǎn)視圖

shouldAutorotateToInterfaceOrientation

支持或禁止自動(dòng)旋轉(zhuǎn)

支持

進(jìn)行旋轉(zhuǎn)視圖前

willAnimateRotationToInterfaceOrientation

用于調(diào)整旋轉(zhuǎn)視圖

2 MVC

·在iOS中,多數(shù)數(shù)據(jù)源視圖控件(View)都有一個(gè)dataSource屬性,數(shù)據(jù)源通過(guò)與控制器(Controller)交互,間接地從我們定義的數(shù)據(jù)模型(Model)中獲取數(shù)據(jù),視圖和控制器之間可以相互訪問(wèn),模型既不能訪問(wèn)視圖也不能訪問(wèn)控制器,這種模式是MVC;·視圖是用戶在屏幕上看到的,模型提供數(shù)據(jù),控制器是它們的中介。

3 UIView

UIView是UIResponder的子類,是許多常用控件的父類,如UIScrollView、UILabel、UIControl和UIPickerView等。屏幕上所有的UI元素都是控件,控件指的就是UIView類或者子類。

·Apple將所有控件的基本屬性都封裝到UIView中,如frame、bounds、center、backgroundColor、hidden、alpha、opaque和userInteractionEnabled等;

·每個(gè)controller都對(duì)應(yīng)一個(gè)默認(rèn)的UIView對(duì)象,該控件的大小是整個(gè)屏幕,每個(gè)UIView對(duì)象都是容器,都被該控件所容納。在一個(gè)控制器.m文件中,self.view就是調(diào)用控制器的默認(rèn)UIView。

UIView有三個(gè)結(jié)構(gòu)體CGPoint,CGRect,CGSize。CGPoint確定了view的起始坐標(biāo)

CGSize確定view的長(zhǎng)寬;CGRect確定了整個(gè)視圖位置和大小。

/* 關(guān)于UIView隱藏屬性、alpha屬性和不透明屬性之間有什么區(qū)別? */
[_uiview setHidden:YES];
[_uiview setAlpha:0.0f];
/* 差異很微妙。根據(jù)UIView文檔:
opaque 告訴系統(tǒng)視圖沒(méi)有透明度,因此渲染速度更快,因?yàn)榭梢蕴^(guò)混合計(jì)算;
hidden 是布爾屬性,僅更改當(dāng)前視圖的可見(jiàn)性并將其從 ui 事件中隱藏;
alpha 是一個(gè)動(dòng)畫(huà)屬性。
設(shè)置alpha=0.0f或hidden=YES具有相同的視覺(jué)效果。然而,當(dāng)您有大量嵌套視圖時(shí),使用hidden 不僅在圖形意義上而且從UI事件中實(shí)際隱藏視圖可能會(huì)導(dǎo)致更有效的響應(yīng)者鏈. */

3.1 Frame和Bounds

frame和bounds都是UIView的屬性。

·bounds通常用來(lái)描述視圖的大小,bounds大小改變時(shí),當(dāng)前視圖的中心點(diǎn)不會(huì)發(fā)生改變,當(dāng)前視圖的大小發(fā)生改變。bounds改變位置時(shí),改變的是子視圖的位置,自身沒(méi)有影響,實(shí)質(zhì)上改變了當(dāng)前視圖的坐標(biāo)系原點(diǎn);
·frame用來(lái)描述視圖的位置(origin)和大小(size),當(dāng)前視圖的位置是以父視圖坐標(biāo)系來(lái)確定。frame大小改變時(shí),當(dāng)前視圖的坐標(biāo)系原點(diǎn)不會(huì)改變,當(dāng)前視圖的大小發(fā)生改變。使用frame的布局是唯一確定的,不會(huì)隨父視圖變化而變化,除非在某個(gè)時(shí)間點(diǎn)再次設(shè)置了frame。

3.2 CALayer

CALayer是屏幕上的一個(gè)具有可見(jiàn)內(nèi)容的矩形區(qū)域,每個(gè)UIView都有一個(gè)根CALayer,其所有的繪制(視覺(jué)效果)都是在這個(gè)layer上進(jìn)行的。

通過(guò)UIView的layer屬性可以訪問(wèn)這個(gè)層。

3.3 UITextView

UITextView是UIScrollView的子類,具有UIScrollView的屬性和方法,包括frame、bounds和backgroundColor等。

UITextView *textmtview = [[UITextView alloc] initWithFrame:CGRectMake(80, 365, 250, 50)];  // Initialize

富文本字符串:AttributedString可以分為NSAttributedStringNSMutableAttributedString,通過(guò)將AttributedString賦值給UILabel、UITextField或UITextView的attributedText屬性來(lái)添加文字樣式。

NSTextAttachment該類使用文本附件對(duì)象作為附件屬性的值(存儲(chǔ)在鍵下的富文本字符串中)。

NSTextAttachment* attch = [[NSTextAttachment alloc] init];
CGFloat diameter = [self fontLineHeight:[UIFont systemFontOfSize:14]];
attch.image = [UIImage imageNamed:@"waybill_detail_help"];
attch.bounds = CGRectMake(0, -5, diameter, diameter);
NSAttributedString* attStr = [NSAttributedString attributedStringWithAttachment:attch];
[attMutStr appendAttributedString:attStr];

3.4 UITableView

3.4.1 數(shù)據(jù)源和代理

·視圖對(duì)象:表視圖只管理表中數(shù)據(jù)的表示,而不管理數(shù)據(jù)本身。

·數(shù)據(jù)源:UITableView的數(shù)據(jù)源用于提供數(shù)據(jù)行數(shù)以及每一行顯示的數(shù)據(jù)等,數(shù)據(jù)源通常是遵守UITableViewDataSource協(xié)議的對(duì)象。

UITableViewDataSource協(xié)議:

表視圖數(shù)據(jù)源協(xié)議,該協(xié)議聲明了管理表視圖數(shù)據(jù)和cell的方法。數(shù)據(jù)源對(duì)象響應(yīng)表中與數(shù)據(jù)相關(guān)的請(qǐng)求。它還可以直接管理表的數(shù)據(jù),或者與app的其他部分協(xié)調(diào)一起來(lái)管理該數(shù)據(jù)。

@protocol UITableViewDataSource<NSObject>
@required
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;  // 設(shè)置表視圖每個(gè)分組的行數(shù)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;  // 控制每一行返回的內(nèi)容
@optional
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;  // 設(shè)置分區(qū)數(shù)
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;  // 設(shè)置分區(qū)頭的內(nèi)容
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;  // 控制Cell是否可以編輯
// Other...
@end

·代理:設(shè)置UITableView的代理對(duì)象來(lái)響應(yīng)事件,比如選中某一行,代理通常是遵守UITableViewDelegate協(xié)議的對(duì)象。使用表視圖通常需要遵守UITableViewDataSource和UITableViewDelegate這兩個(gè)協(xié)議。

UITableViewDelegate協(xié)議:

用于管理選擇、配置節(jié)頁(yè)眉和頁(yè)腳、刪除和重新排序單元格以及在表格視圖中執(zhí)行其他操作的方法。使用此協(xié)議的方法來(lái)管理以下功能:創(chuàng)建和管理自定義頁(yè)眉和頁(yè)腳視圖;指定行、頁(yè)眉和頁(yè)腳的自定義高度;提供高度估計(jì)以獲得更好的滾動(dòng)支持;縮進(jìn)行內(nèi)容;響應(yīng)行選擇等。

// Cell被點(diǎn)擊后需要做什么
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
// 告訴UITableView每一個(gè)Cell的高度是多少
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

3.4.2 cell重用

·UITableView有一個(gè)重用池機(jī)制來(lái)管理UITableViewCell,當(dāng)列表滑動(dòng)時(shí),一部分cell會(huì)移出窗口,UITableView默認(rèn)只加載在屏幕上顯示的cell,窗口外的cell會(huì)被放入一個(gè)對(duì)象池里等待復(fù)用。當(dāng)UITableView要求dataSource返回UITableViewCell時(shí),dataSource會(huì)先嘗試從對(duì)象池獲取一個(gè),如果池中有未使用的UITableViewCell,dataSource會(huì)用新的數(shù)據(jù)配置這個(gè)UITableViewCell,然后返回給UITableView,重新顯示到窗口中,從而避免創(chuàng)建新對(duì)象。

·UITableViewCell有個(gè)NSString *reuseIdentifier屬性,可以在初始化UITableViewCell的時(shí)候傳入一個(gè)特定的字符串標(biāo)識(shí)來(lái)設(shè)置reuseIdentifier。當(dāng)UITableView要求dataSource返回UITableViewCell時(shí),先通過(guò)一個(gè)字符串標(biāo)識(shí)到對(duì)象池中嘗試獲取對(duì)應(yīng)類型的UITableViewCell對(duì)象,如果沒(méi)有對(duì)應(yīng)類型的對(duì)象,就用這個(gè)標(biāo)識(shí)來(lái)初始化一個(gè)UITableViewCell對(duì)象。

重用方法:定義cell的標(biāo)識(shí)、從對(duì)象池里取cell、判斷取出cell是否為空,為空就初始化cell。

- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {static NSString *showUserInfoCellIdentifier = @"ShowUserInfoCell";UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:showUserInfoCellIdentifier];if (cell == nil) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:showUserInfoCellIdentifier];}return cell;
}

3.5 UILabel

UILabel 是基礎(chǔ)的文本組件。

// 自適應(yīng)計(jì)算UILabel高度
+ (CGFloat)calculateLabelHeightWithString:(NSString *)string font:(UIFont *)font labelWidth:(CGFloat)labelWidth {NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;CGFloat height = [string boundingRectWithSize:CGSizeMake(labelWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font,NSParagraphStyleAttributeName:paragraphStyle.copy} context:nil].size.height;short scale = [UIScreen mainScreen].scale;height = scale * height;height = ceilf(height);return height / scale;
}

4 UIViewController

UIViewController是視圖控制器,它由控制器+view組成。它能夠完成以下功能:

  1. 控制視圖的代碼邏輯,并擁有自己的視圖

  2. 控制器與控制器之間的通信

  3. 視圖與Model之間的傳值

  4. 添加子控制器

  5. 展示界面信息

  6. 添加子控件

4.1 UITabBarController

UITabBarController就是多個(gè)ViewController的容器,他們之間的層級(jí)是平行的,它會(huì)在底部添加一個(gè)TabBar的UIView,通過(guò)點(diǎn)擊TabBar上的按鈕tabBarItem來(lái)切換對(duì)應(yīng)的ViewController。

4.2 UINavigationController

UITabBarController一般配合UINavigationController來(lái)使用,這樣可以實(shí)現(xiàn)多Tab,多棧跳轉(zhuǎn)頁(yè)面視圖。

4.3 Segue

類型

作用

Show (Push)

此segue調(diào)用showViewController: sender:方法顯示新內(nèi)容。對(duì)于大多數(shù)視圖控制器,show segue 在源視圖控制器上以modal方式呈現(xiàn)新內(nèi)容。但UISplitViewController和UINavigationController類會(huì)重寫(xiě)showViewController: sender:方法,以根據(jù)自身設(shè)計(jì)處理呈現(xiàn)方式。如在UINavigationController中,視圖控制器會(huì)被push到其導(dǎo)航堆棧。

Show Detail (Replace)

此segue調(diào)用showDetailViewController: sender:方法顯示新內(nèi)容。Show Detail segue僅與嵌入在UISplitViewController對(duì)象內(nèi)的視圖控制器相關(guān),此時(shí)分割視圖用新內(nèi)容替換detail controller。在其他視圖控制器中,show detail會(huì)以modal形式呈現(xiàn)新內(nèi)容。

Present Modally

調(diào)用方法presentViewController: animated: completion:,使用指定presentation style和transition style以modal形式呈現(xiàn)新內(nèi)容

Present As Popover

在horizontally regular environment,視圖控制器顯示在彈出窗口中;在horizontally compact environment,視圖控制器使用全屏模式顯示。

5 UIScreen

// 帶有狀態(tài)欄的 Rect 
CGRect bound = [UIScreen mainScreen].bounds;
// 不帶有狀態(tài)欄的 Rect 
CGRect frame = [UIScreen mainScreen].applicationFrame;
// 設(shè)備的自然分辨率
float scale = [UIScreen mainScreen].scale;

PPI(Pixel Per Inch by diagonal):表示沿著對(duì)角線,每英寸所擁有的像素(Pixel)數(shù)目。PPI數(shù)值越高,代表顯示屏能夠以越高的密度顯示圖像,即通常所說(shuō)的分辨率越高、顆粒感越弱。在同樣的邏輯坐標(biāo)系下(320×480),1 point = scale*pixel(在iPhone4~6中,縮放因子scale=2;在iPhone6+中,縮放因子scale=3)??梢岳斫鉃?#xff1a;scale=絕對(duì)長(zhǎng)度比(point/pixel)=單位長(zhǎng)度內(nèi)的數(shù)量比(pixel/point)。

1 MAMapkit

高德地圖 iOS SDK 是一套基于?iOS 8.0?及以上版本的地圖應(yīng)用程序開(kāi)發(fā)接口,供開(kāi)發(fā)者在自己的iOS應(yīng)用中加入地圖相關(guān)的功能,包括:地圖顯示(含室內(nèi)、室外地圖)、與地圖交互、在地圖上繪制、興趣點(diǎn)搜索、地理編碼、離線地圖等功能。

高德地圖 iOS SDK 專業(yè)版是在 iOS SDK 已有服務(wù)的基礎(chǔ)上,新增支持了自定義地圖在線加載、自定義地圖元素紋理等功能,便于開(kāi)發(fā)者完成基于自身場(chǎng)景的更深層、更個(gè)性化地圖的開(kāi)發(fā)需求。

·注冊(cè)

使用高德地圖,首先需要注冊(cè)獲取應(yīng)用KEY,申請(qǐng)流程見(jiàn)官網(wǎng)。

·導(dǎo)入第三方庫(kù)

自動(dòng)配置(使用Cocoapods):

1)編輯Podfile

platform :ios, '15.0' #手機(jī)的系統(tǒng)
target 'demogmap' dopod 'AMap2DMap' #2D地圖SDK(2D和3D不能同時(shí)使用)pod 'AMapSearch' #搜索功能
end

2)安裝依賴庫(kù)(M1)

sudo arch -x86_64 gem install ffi
arch -x86_64 pod install

手動(dòng)配置:

1)添加依賴庫(kù)

2)添加資源文件

需要引入的資源文件包括:AMap.bundle,其中:AMap.bundle 在 MAMapKit.framework 包中,AMap.bundle資源文件中存儲(chǔ)了定位、默認(rèn)大頭針標(biāo)注視圖等圖片,可利用這些資源圖片進(jìn)行開(kāi)發(fā)。

申請(qǐng)好key值后,需要在application里配置用戶的key值

3)修改Info.plist,增加如下鍵值

    <key>NSAppTransportSecurity</key><dict><key>NSAllowsArbitraryLoads</key><true/></dict><key>NSLocationAlwaysAndWhenInUseUsageDescription</key><string>始終允許訪問(wèn)位置信息</string><key>NSLocationWhenInUseUsageDescription</key><string>使用應(yīng)用期間允許訪問(wèn)位置信息</string>

4)在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中添加申請(qǐng)的key

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// Override point for customization after application launch.[[AMapServices sharedServices] setEnableHTTPS:YES];[AMapServices sharedServices].apiKey = @"4ca2e61dc9bd7504896f99b4558a2e7b";return YES;
}

1.1 定位

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view._mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];_mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;[_mapView setShowsUserLocation:YES]; // 顯示定位[_mapView setUserTrackingMode:MAUserTrackingModeFollow];[self.view addSubview:_mapView];[_mapView setDelegate:self];  // 設(shè)置委托
}

1.2 手勢(shì)

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.UILongPressGestureRecognizer *lpress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];lpress.delegate = self;[_mapView addGestureRecognizer:lpress];
}- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {return YES;
}- (void)longPress:(UIGestureRecognizer*)gestureRecognizer{if (gestureRecognizer.state == UIGestureRecognizerStateEnded){return;}[_mapView removeAnnotation:_pointAnnotation];CGPoint touchPoint = [gestureRecognizer locationInView:_mapView]; //獲取坐標(biāo)點(diǎn)CLLocationCoordinate2D touchMapCoordinate = [_mapView convertPoint:touchPoint toCoordinateFromView:_mapView];_pointAnnotation.coordinate = touchMapCoordinate;_pointAnnotation.title = @"選定位置";[_mapView addAnnotation:_pointAnnotation];[self.mapView addOverlay:[MACircle circleWithCenterCoordinate:touchMapCoordinate radius:1000]];[self setLocationWithLatitude:touchMapCoordinate.latitude AndLongitude:touchMapCoordinate.longitude];
}

1.3 標(biāo)注

- (MAAnnotationView*)mapView:(MAMapView *)mapView viewForAnnotation:(id <MAAnnotation>)annotation {if ([annotation isKindOfClass:[MAPointAnnotation class]]){static NSString *pointReuseIndetifier = @"pointReuseIndetifier";MAPinAnnotationView *annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndetifier];if (annotationView == nil){annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndetifier];}annotationView.canShowCallout               = YES;annotationView.animatesDrop                 = YES;annotationView.draggable                    = YES;annotationView.rightCalloutAccessoryView    = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];annotationView.pinColor                     = [self.annotations indexOfObject:annotation] % 3;return annotationView;}return nil;
}

1.4 描繪蒙層

- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id<MAOverlay>)overlay {if([overlay isKindOfClass:[MACircle class]]){MACircleRenderer *render = [[MACircleRenderer alloc] initWithCircle:overlay];render.fillColor = [UIColor colorWithRed:1.0 green:0.8 blue:0.0 alpha:0.8];  //圓圈的填充顏色render.strokeColor = UIColor.blueColor;  //圓圈的輪廓顏色render.lineWidth = 3.f;  //圓圈輪廓的粗細(xì)return render;}return nil;
}

1.5 發(fā)起路徑規(guī)劃搜索

- (IBAction)findWayAction:(id)sender {// 設(shè)置步行路徑規(guī)劃請(qǐng)求參數(shù)AMapWalkingRouteSearchRequest* walkRequest = [[AMapWalkingRouteSearchRequest alloc] init];// 設(shè)置起點(diǎn)walkRequest.origin = [AMapGeoPoint locationWithLatitude:((MAPointAnnotation*)(_annotations[0])).coordinate.latitude longitude:((MAPointAnnotation*)(_annotations[0])).coordinate.longitude];// 點(diǎn)擊設(shè)置終點(diǎn)walkRequest.destination = [AMapGeoPoint locationWithLatitude:((MAPointAnnotation*)(_pointAnnotation)).coordinate.latitude longitude:((MAPointAnnotation*)(_pointAnnotation)).coordinate.longitude];// 發(fā)起路徑搜索,發(fā)起后會(huì)執(zhí)行代理方法[_search AMapWalkingRouteSearch:walkRequest];
}//路線解析
- (MAPolyline *)polylinesForPath:(AMapPath *)path{if (path == nil || path.steps.count == 0){return nil;}NSMutableString *polylineMutableString = [@"" mutableCopy];for (AMapStep *step in path.steps) {[polylineMutableString appendFormat:@"%@;",step.polyline];}NSUInteger count = 0;CLLocationCoordinate2D *coordinates = [self coordinatesForString:polylineMutableString coordinateCount:&count parseToken:@";"];MAPolyline *polyline = [MAPolyline polylineWithCoordinates:coordinates count:count];free(coordinates), coordinates = NULL;return polyline;
}//解析經(jīng)緯度
- (CLLocationCoordinate2D *)coordinatesForString:(NSString *)stringcoordinateCount:(NSUInteger *)coordinateCountparseToken:(NSString *)token{if (string == nil){return NULL;}if (token == nil){token = @",";}NSString *str = @"";if (![token isEqualToString:@","]){str = [string stringByReplacingOccurrencesOfString:token withString:@","];}else{str = [NSString stringWithString:string];}NSArray *components = [str componentsSeparatedByString:@","];NSUInteger count = [components count] / 2;if (coordinateCount != NULL){*coordinateCount = count;}CLLocationCoordinate2D *coordinates = (CLLocationCoordinate2D*)malloc(count * sizeof(CLLocationCoordinate2D));for (int i = 0; i < count; i++){coordinates[i].longitude = [[components objectAtIndex:2 * i]     doubleValue];coordinates[i].latitude  = [[components objectAtIndex:2 * i + 1] doubleValue];}return coordinates;
}

2 相機(jī)和相冊(cè)

iOS開(kāi)發(fā)中,通常獲取照片的方式有三種:1.直接調(diào)用攝像頭拍照 2.從相冊(cè)中選擇 3.從圖庫(kù)中選擇。 通常使用到的類或框架有UIImagePickerController、AssetsLibrary(iOS 4 - iOS 9)、PhotoKit(iOS8)等。

2.1 UIImagePickerController

UIImagePickerController 是系統(tǒng)提供的用來(lái)獲取圖片和視頻的接口。用 UIImagePickerController 類來(lái)獲取圖片視頻,大體分為以下幾個(gè)步驟:

  1. 初始化 UIImagePickerController 類;

  2. 設(shè)置 UIImagePickerController 實(shí)例的數(shù)據(jù)來(lái)源類型;

  3. 設(shè)置代理;

  4. 如果需要做圖片修改的話設(shè)置 allowsEditing = YES。

// 需遵守協(xié)議 UIImagePickerControllerDelegate, UINavigationControllerDelegate
_uiipc = [[UIImagePickerController alloc] init];
//獲取照片的類型
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {_uiipc.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
//設(shè)置代理
_uiipc.delegate = self;
//是否允許編輯
_uiipc.allowsEditing = YES;#pragma mark UIImagePickerControllerDelegate- (void)imagePickerControllerDidCancel:(UIImagePickerController*)picker {[picker dismissViewControllerAnimated:YES completion:nil];
}- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {UIImageView* imgview = _uiiv;// 獲取選擇的圖片UIImage* org = [info objectForKey:UIImagePickerControllerOriginalImage];// 修改圖片UIImage* cir = [self CircleImageWithRef:org AndDiameter:100.0f AndBorderWidth:2.0f AndBorderColor:[UIColor redColor]];// 替換原來(lái)的頭像[picker dismissViewControllerAnimated:YES completion:^(void) {[UIView animateWithDuration:0.5f animations:^(void) {[self.view setAlpha:1.0f];[imgview setImage:cir];} completion:nil];UIAlertController* uiac = [UIAlertController alertControllerWithTitle:@"提示" message:@"更改頭像" preferredStyle:UIAlertControllerStyleAlert];[uiac addAction:[UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]];[self presentViewController:uiac animated:YES completion:nil];}];
}

2.2 AssetsLibrary

AssetsLibrary框架包含ALAssetsLibrary、ALAssetsGroup、ALAsset、ALAssetsFilter、ALAssetRepresentation五個(gè)類,提供從相冊(cè)中讀取相片、將相片保存到相冊(cè),獲取相冊(cè)信息,增加相冊(cè)等功能。

·ALAssetsLibrary類用來(lái)構(gòu)建資源庫(kù)對(duì)象,這個(gè)對(duì)象用來(lái)整體操作系統(tǒng)的相冊(cè)資源,可以實(shí)現(xiàn)查看相冊(cè)列表,增加相冊(cè),保存圖片到相冊(cè)等功能,例如enumerateGroupsWithTypes方法列舉所有相冊(cè);

·ALAssetsGroup相冊(cè)類,通過(guò)valueForProperty方法查看不同屬性的值,如:ALAssetsGroupPropertyName相冊(cè)名。ALAssetsGroup類有幾個(gè)方法,posterImage方法是相冊(cè)的封面圖片,numberOfAssets方法獲取該相冊(cè)的圖片視頻數(shù)量,通過(guò)enumerateAssetsUsingBlock方法列舉出所有照片,使用setAssetsFilter:(ALAssetsFilter *)filter過(guò)濾照片或者視頻等;

·ALAsset類也可以通過(guò)valueForProperty方法查看不同屬性的值,如:ALAssetPropertyType,asset的類型,有三種ALAssetTypePhoto, ALAssetTypeVideo or ALAssetTypeUnknown。另外還可以通過(guò)該方法獲取ALAssetPropertyLocation(照片位置),ALAssetPropertyDuration(視頻時(shí)間),ALAssetPropertyDate(照片拍攝日期)等;

·ALAssetRepresentation類是ALAsset類的defaultRepresentation方法的返回值類型,該類的作用就是獲取該資源圖片的詳細(xì)資源信息。

2.3 PhotoKit

在 iOS 和 macOS 中,PhotoKit是App在使用、管理圖片和視頻的框架,而且還包括了iCloud上面的圖片以及實(shí)時(shí)照片。PhotoKit 提供了支持為照片應(yīng)用程序構(gòu)建照片編輯擴(kuò)展的類。在 iOS、macOS 和 tvOS 中,PhotoKit 還提供對(duì)照片應(yīng)用程序管理的照片和視頻資產(chǎn)的直接訪問(wèn)。

3 QuartzCore

QuartzCore(包含CoreAnimation)框架,是iOS系統(tǒng)的基本渲染框架,是一個(gè)OC語(yǔ)言框架,是一套基于CoreGraphics的OC語(yǔ)言封裝,封裝出了基本渲染類CALayer。QuartzCore框架用于提供iOS開(kāi)發(fā)中的視覺(jué)反饋,開(kāi)發(fā)的界面都是QuartzCore框架中CALayer圖層合成的結(jié)果,CALayer提供了接口用于給自己添加Animation。

3.1 CALayer

在iOS中,UIView控件并不是直接顯示在屏幕上,而是在創(chuàng)建UIView視圖對(duì)象的時(shí)候內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)圖層即CALayer對(duì)象,而UIView把要顯示的東西繪制在層上,待到需要顯示時(shí)硬件將所有的層拷貝,然后按Z軸的高低合成最終的顯示結(jié)果。CALayer本質(zhì)上是一塊包含一幅位圖的緩沖區(qū),由視圖創(chuàng)建的層為隱式層,而手動(dòng)創(chuàng)建的層稱為顯式層。CALayer實(shí)現(xiàn)了CAMediaTiming協(xié)議,CALayer通過(guò)CAMediaTiming協(xié)議實(shí)現(xiàn)了一個(gè)有層級(jí)關(guān)系的時(shí)間系統(tǒng)。除了CALayer,CAAnimation也采納了此協(xié)議,用來(lái)實(shí)現(xiàn)動(dòng)畫(huà)的時(shí)間系統(tǒng)。

樹(shù)狀結(jié)構(gòu)

Layer也和View一樣存在著一個(gè)層級(jí)樹(shù)狀結(jié)構(gòu),稱之為圖層樹(shù)(Layer Tree),直接創(chuàng)建的或者通過(guò)UIView獲得的用于顯示的圖層樹(shù),稱之為模型樹(shù)(Model Tree),模型樹(shù)中的對(duì)象是應(yīng)用程序與之交互的對(duì)象。此樹(shù)中的對(duì)象是存儲(chǔ)任何動(dòng)畫(huà)的目標(biāo)值的模型對(duì)象。每當(dāng)更改圖層的屬性時(shí),都使用其中一個(gè)對(duì)象。模型樹(shù)負(fù)責(zé)存儲(chǔ)動(dòng)畫(huà)的目標(biāo)值的模型對(duì)象。每當(dāng)更改圖層的屬性時(shí),它都會(huì)把數(shù)據(jù)存儲(chǔ)下來(lái)。

模型樹(shù)的背后還存在兩份圖層樹(shù)的拷貝,一個(gè)是呈現(xiàn)樹(shù)(Presentation Tree),一個(gè)是渲染樹(shù)(Render Tree)。呈現(xiàn)樹(shù)可以通過(guò)普通layer(其實(shí)就是模型樹(shù))的layer.presentationLayer獲得,而模型樹(shù)則可以通過(guò)modelLayer屬性獲得。呈現(xiàn)樹(shù)通過(guò)圖層樹(shù)中所有圖層的呈現(xiàn)圖層所形成。注意呈現(xiàn)圖層僅僅當(dāng)圖層首次被提交(就是首次第一次在屏幕上顯示)的時(shí)候創(chuàng)建,所以在那之前調(diào)用-presentationLayer將會(huì)返回nil。呈現(xiàn)樹(shù)中的對(duì)象反映屏幕上顯示的當(dāng)前值。您永遠(yuǎn)不應(yīng)該修改此樹(shù)中的對(duì)象。相反,您可以使用這些對(duì)象來(lái)讀取當(dāng)前動(dòng)畫(huà)值,也許是為了從這些值開(kāi)始創(chuàng)建新動(dòng)畫(huà)。self.layer = self.layer.modelLayer 、self.layer != self.layer.presentationLayer。layer本身其實(shí)就是一個(gè)模型layer,只不過(guò)它擁有presentationLayer。

呈現(xiàn)樹(shù)的屬性值和動(dòng)畫(huà)運(yùn)行過(guò)程中界面上看到的是一致的,而渲染樹(shù)是私有的,是對(duì)呈現(xiàn)樹(shù)的數(shù)據(jù)進(jìn)行渲染。為了不阻塞主線程,渲染的過(guò)程是在單獨(dú)的進(jìn)程或線程中進(jìn)行的。

@property(nonatomic,readonly,retain) CALayer *layer;  // 通過(guò)UIView的layer屬性可以訪問(wèn)這個(gè)層

UIView與CALayer

當(dāng)UIView需要顯示時(shí),會(huì)調(diào)用drawRect:方法將所有內(nèi)容繪制在自己的CALayer上,繪圖完畢后系統(tǒng)再將圖層拷貝到屏幕上,從而完成了UIView的顯示。UIView的animation實(shí)現(xiàn)的動(dòng)畫(huà)本質(zhì)上也是通過(guò)CALayer來(lái)實(shí)現(xiàn)的,iOS系統(tǒng)中CALayer的很多屬性都是隱含有動(dòng)畫(huà)效果的,如果不想要隱式動(dòng)畫(huà)或者想要顯示動(dòng)畫(huà)效果,都可以通過(guò)CATransaction來(lái)設(shè)置是否顯示動(dòng)畫(huà)效果。同時(shí),在CATransaction內(nèi)可同時(shí)修改多個(gè)屬性,然后再一并同時(shí)渲染,另外CATransaction還是可嵌套的。與CALayer相比,UIView還具有事件處理的功能,可以跟用戶進(jìn)行交互。CALayer的性能更高,因?yàn)樗痪邆涮幚硎录晚憫?yīng)鏈(responder chain)等(CALayer直接繼承于NSObject,而UIView繼承于UIResponder,更加輕量級(jí)。UIView側(cè)重于對(duì)顯示內(nèi)容的管理,CALayer側(cè)重于對(duì)內(nèi)容的繪制。對(duì)于UIView所管理的內(nèi)容,顯示任何圖形都會(huì)受到CALayer的影響。UIView依賴于CALayer提供的內(nèi)容,CALayer依賴于UIView提供的容器來(lái)顯示繪制的內(nèi)容。UIView與CALayer都有樹(shù)狀層級(jí)結(jié)構(gòu),CALayer內(nèi)部有SubLayers,UIView內(nèi)部也有SubViews。

CALayer重要屬性

屬性

作用

position

設(shè)置CALayer在父層上的位置,以父層的左上角為原點(diǎn)(0,0)

anchorPoint

決定CALayer哪個(gè)點(diǎn)會(huì)在position屬性指定的位置,以自己的左上角為原點(diǎn)(0,0),最大的坐標(biāo)位置為右下角為(1,1),其默認(rèn)位置為中心點(diǎn)(0.5,0.5)

bounds

設(shè)置CALayer對(duì)象的尺寸

隱式動(dòng)畫(huà)

每一個(gè)UIView內(nèi)部都默認(rèn)關(guān)聯(lián)著一個(gè)CALayer,我們可稱這個(gè)Layer為Root Layer(根層)。所有的非Root Layer的顯式CALayer對(duì)象都存在隱式動(dòng)畫(huà)。當(dāng)對(duì)顯式CALayer對(duì)象的部分屬性進(jìn)行修改時(shí),默認(rèn)會(huì)自動(dòng)產(chǎn)生一些動(dòng)畫(huà)效果, 這些屬性稱為Animatable Properties。

// 通過(guò)動(dòng)畫(huà)事務(wù)(CATransaction)關(guān)閉默認(rèn)的隱式動(dòng)畫(huà)效果
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.myview.layer.position = CGPointMake(10, 10);
[CATransaction commit];

常見(jiàn)Animatable Properties

屬性

作用

bounds

用于設(shè)置CALayer的寬度和高度;修改這個(gè)屬性會(huì)產(chǎn)生縮放動(dòng)畫(huà)

backgroundColor

用于設(shè)置CALayer的背景色;修改這個(gè)屬性會(huì)產(chǎn)生背景色的漸變動(dòng)畫(huà)

position

用于設(shè)置CALayer的位置;修改這個(gè)屬性會(huì)產(chǎn)生平移動(dòng)畫(huà)

3.2 Core Animation

IOS 動(dòng)畫(huà)主要是指Core Animation框架。官方使用文檔地址為:Core Animation Programming Guide。
Core Animation是IOS和OS X平臺(tái)上負(fù)責(zé)圖形渲染與動(dòng)畫(huà)的基礎(chǔ)框架。Core Animation可以作用與動(dòng)畫(huà)視圖或者其他可視元素,為你完成了動(dòng)畫(huà)所需的大部分繪幀工作。你只需要配置少量的動(dòng)畫(huà)參數(shù)(如開(kāi)始點(diǎn)的位置和結(jié)束點(diǎn)的位置)即可使用Core Animation的動(dòng)畫(huà)效果。Core Animation將大部分實(shí)際的繪圖任務(wù)交給了圖形硬件來(lái)處理,圖形硬件會(huì)加速圖形渲染的速度。這種自動(dòng)化的圖形加速技術(shù)讓動(dòng)畫(huà)擁有更高的幀率并且顯示效果更加平滑,不會(huì)加重CPU的負(fù)擔(dān)而影響程序的運(yùn)行速度。

Core Animation核心動(dòng)畫(huà)是一組iOS提供的動(dòng)畫(huà)處理API,它是跨Mac OS X和iOS平臺(tái)的。Core Animation的動(dòng)畫(huà)執(zhí)行過(guò)程都是在后臺(tái)操作的,不會(huì)阻塞主線程。Core Animation作用于CALayer上而并非UIView,修改的值都是假象,layer的真實(shí)位置并沒(méi)有發(fā)生改變。

作用

CABasicAnimation

基本動(dòng)畫(huà)。CABasicAnimation有三個(gè)比較重要的屬性:fromValue、toValue、byValue,這三個(gè)屬性都是可選的,但不能同時(shí)多于兩個(gè)為非空,最終都是為了確定animation變化的起點(diǎn)和終點(diǎn)。設(shè)置了動(dòng)畫(huà)的起點(diǎn)和終點(diǎn)之后,中間的值都是通過(guò)插值方式計(jì)算出來(lái)的,插值計(jì)算的結(jié)果由timingFunction指定,默認(rèn)timingFunction為nil,會(huì)使用liner的,也就是變化是均勻的。

CAKeyframeAnimation

幀動(dòng)畫(huà)。任何動(dòng)畫(huà)要表現(xiàn)出運(yùn)動(dòng)或者變化,至少需要兩個(gè)不同的關(guān)鍵狀態(tài),而中間的狀態(tài)的變化可以通過(guò)插值計(jì)算完成,從而形成補(bǔ)間動(dòng)畫(huà),表示關(guān)鍵狀態(tài)的幀叫做關(guān)鍵幀.CABasicAnimation其實(shí)可以看作一種特殊的關(guān)鍵幀動(dòng)畫(huà),只有頭尾兩個(gè)關(guān)鍵幀.CAKeyframeAnimation則可以支持任意多個(gè)關(guān)鍵幀,關(guān)鍵幀有兩種方式來(lái)指定,使用path或者使用values,path是一個(gè)CGPathRef的值,且path只能對(duì)CALayer的 anchorPoint 和 position 屬性起作用,且設(shè)置了path之后values就不再起效了.而values則更加靈活. keyTimes這個(gè)可選參數(shù)可以為對(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í)間是平分的.?
還可以通過(guò)設(shè)置可選參數(shù)timingFunctions(CAKeyframeAnimation中timingFunction是無(wú)效的)為關(guān)鍵幀之間的過(guò)渡設(shè)置timingFunction,如果values有n個(gè)元素,那么timingFunctions則應(yīng)該有n-1個(gè).但很多時(shí)候并不需要timingFunctions,因?yàn)橐呀?jīng)設(shè)置了夠多的關(guān)鍵幀了,比如沒(méi)1/60秒就設(shè)置了一個(gè)關(guān)鍵幀,那么幀率將達(dá)到60FPS,完全不需要相鄰兩幀的過(guò)渡效果(當(dāng)然也有可能某兩幀 值相距較大,可以使用均勻變化或者增加幀率,比如每0.01秒設(shè)置一個(gè)關(guān)鍵幀).

在關(guān)鍵幀動(dòng)畫(huà)中還有一個(gè)非常重要的參數(shù),那便是calculationMode,計(jì)算模式.其主要針對(duì)的是每一幀的內(nèi)容為一個(gè)座標(biāo)點(diǎn)的情況,也就是對(duì)anchorPoint 和 position 進(jìn)行的動(dòng)畫(huà).當(dāng)在平面座標(biāo)系中有多個(gè)離散的點(diǎn)的時(shí)候,可以是離散的,也可以直線相連后進(jìn)行插值計(jì)算,也可以使用圓滑的曲線將他們相連后進(jìn)行插值計(jì)算. calculationMode目前提供如下幾種模式 kCAAnimationLinear?
kCAAnimationDiscrete?
kCAAnimationPaced?
kCAAnimationCubic?
kCAAnimationCubicPaced

kCAAnimationLinear?calculationMode的默認(rèn)值,表示當(dāng)關(guān)鍵幀為座標(biāo)點(diǎn)的時(shí)候,關(guān)鍵幀之間直接直線相連進(jìn)行插值計(jì)算;?
kCAAnimationDiscrete?離散的,就是不進(jìn)行插值計(jì)算,所有關(guān)鍵幀直接逐個(gè)進(jìn)行顯示;?
kCAAnimationPaced?使得動(dòng)畫(huà)均勻進(jìn)行,而不是按keyTimes設(shè)置的或者按關(guān)鍵幀平分時(shí)間,此時(shí)keyTimes和timingFunctions無(wú)效;?
kCAAnimationCubic?對(duì)關(guān)鍵幀為座標(biāo)點(diǎn)的關(guān)鍵幀進(jìn)行圓滑曲線相連后插值計(jì)算,對(duì)于曲線的形狀還可以通過(guò)tensionValues,continuityValues,biasValues來(lái)進(jìn)行調(diào)整自定義,這里的數(shù)學(xué)原理是Kochanek–Bartels spline,這里的主要目的是使得運(yùn)行的軌跡變得圓滑;?
kCAAnimationCubicPaced?看這個(gè)名字就知道和kCAAnimationCubic有一定聯(lián)系,其實(shí)就是在kCAAnimationCubic的基礎(chǔ)上使得動(dòng)畫(huà)運(yùn)行變得均勻,就是系統(tǒng)時(shí)間內(nèi)運(yùn)動(dòng)的距離相同,此時(shí)keyTimes以及timingFunctions也是無(wú)效的.

CATransition

轉(zhuǎn)場(chǎng)動(dòng)畫(huà)。

CAAnimationGroup

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

CAMediaTimingFunction

提供了兩種獲得時(shí)間函數(shù)的方式:使用預(yù)定義的五種時(shí)間函數(shù)或通過(guò)給點(diǎn)兩個(gè)控制點(diǎn)得到一個(gè)時(shí)間函數(shù)。有五種預(yù)定義的時(shí)間函數(shù):kCAMediaTimingFunctionLinear
kCAMediaTimingFunctionEaseIn
kCAMediaTimingFunctionEaseOut
kCAMediaTimingFunctionEaseInEaseOut
kCAMediaTimingFunctionDefault

CADisplayLink

一個(gè)能讓我們以和屏幕刷新率相同的頻率將內(nèi)容畫(huà)到屏幕上的定時(shí)器。一旦CADisplayLink以特定的模式注冊(cè)到runloop之后,每當(dāng)屏幕需要刷新的時(shí)候,runloop就會(huì)調(diào)用CADisplayLink綁定的target上的selector,這時(shí)target可以讀到 CADisplayLink 的每次調(diào)用的時(shí)間戳,用來(lái)準(zhǔn)備下一幀顯示需要的數(shù)據(jù)。例如一個(gè)視頻應(yīng)用使用時(shí)間戳來(lái)計(jì)算下一幀要顯示的視頻數(shù)據(jù)。在UI做動(dòng)畫(huà)的過(guò)程中,需要通過(guò)時(shí)間戳來(lái)計(jì)算UI對(duì)象在動(dòng)畫(huà)的下一幀要更新的大小等等。依托于設(shè)備屏幕刷新頻率觸發(fā)事件,所以其觸發(fā)時(shí)間上是最準(zhǔn)確的。也是最適合做UI不斷刷新的事件,過(guò)渡相對(duì)流暢,無(wú)卡頓感

仿射變換包括如下所有變換,以及這些變換任意次序次數(shù)的組合:平移、旋轉(zhuǎn)、放縮、剪切、反射

/**
struct CATransform3D
{
CGFloat    m11(x縮放),     m12(y切變),      m13(旋轉(zhuǎn)),     m14();CGFloat    m21(x切變),     m22(y縮放),      m23(),        m24();CGFloat    m31(旋轉(zhuǎn)),      m32(),          m33(),        m34(透視效果,要操作的這個(gè)對(duì)象要有旋轉(zhuǎn)的角度,否則沒(méi)有效果。正直/負(fù)值都有意義);CGFloat    m41(x平移),     m42(y平移),      m43(z平移),   m44();
};
**/

總結(jié):CoreAnimation是跨iOS和macOS的,CoreAnimation在后臺(tái)執(zhí)行動(dòng)畫(huà)而不阻塞主線程,CoreAnimation作用于CALayer而不是UIView。

3.2.1 Core Graphics

Core Graphics是一個(gè)基于C的繪圖專用的API族,它經(jīng)常被稱為QuartZ或QuartZ 2D,是一個(gè)二維繪圖引擎,同時(shí)支持iOS和macOS。它提供了低級(jí)別、輕量級(jí)、高保真度的2D渲染。該框架可以用于基于路徑的繪圖、變換、顏色管理、脫屏渲染,模板、漸變。

iOS系統(tǒng)本身提供了兩套繪圖的框架,即UIBezierPath和Core Graphics。前者所屬UIKit,其實(shí)是對(duì)Core Graphics框架關(guān)于path的進(jìn)一步封裝,CoreGraphics是底層繪制框架,我們實(shí)際會(huì)用到的也就是CG開(kāi)頭的一些底層繪制函數(shù)和變量,這是一個(gè)純C語(yǔ)言框架。使用UIBezierPath繪圖只能在drawRect里進(jìn)行,因?yàn)榈讓右玫缴舷挛?#xff0c;圖形上下文只能在drawRect里獲取,不能在其他方法里面繪圖,比如:不能在awakeFromNib里繪圖。

CoreGraphics和CoreAnimation:它們都是跨iOS和Mac OS 使用的,這點(diǎn)區(qū)別于UIKit,并且CoreAnimation中大量使用到CoreGraphics中的類,因?yàn)閷?shí)現(xiàn)動(dòng)畫(huà)要用到圖形庫(kù)中的東西。

CGContextRef

圖形上下文是一個(gè)CGContextRef類型的數(shù)據(jù),圖形上下文相當(dāng)于畫(huà)板,用于封裝繪圖信息(畫(huà)了什么)和繪圖狀態(tài)(線條大小、顏色等),它決定繪制的輸出目標(biāo)(繪制到什么地方去),目標(biāo)可以是PDF文件、bitmap或者顯示器的窗口。在UIView中,系統(tǒng)會(huì)默認(rèn)創(chuàng)建一個(gè)Layer Graphics Context,它對(duì)應(yīng)UIView的layer屬性,該圖形上下文可以在drawRect:方法中獲取,開(kāi)發(fā)者只能獲取,不能自己重新創(chuàng)建,在該圖層上下文中繪制的圖形,最終會(huì)通過(guò)CALayer顯示出來(lái)。因此,View之所以能顯示東西,完全是因?yàn)樗鼉?nèi)部的layer。

當(dāng) UIView 需要顯示時(shí),它內(nèi)部的層會(huì)準(zhǔn)備好一個(gè) CGContextRef(圖形上下文),然后調(diào)用 delegate(這里就是 UIView)的 drawLayer:inContext: 方法,并且傳入已經(jīng)準(zhǔn)備好的 CGContextRef 對(duì)象。而 UIView 在 drawLayer:inContext: 方法中又會(huì)調(diào)用自己的 drawRect: 方法。平時(shí)在 drawRect: 中通過(guò) UIGraphicsGetCurrentContext() 獲取的就是由層傳入的 CGContextRef 對(duì)象,在 drawRect: 中完成的所有繪圖都會(huì)填入層的 CGContextRef 中,然后被拷貝至屏幕。

5 AVPlayer

AVFoundation是一個(gè)功能齊全的高級(jí)框架,用于在 iOS、macOS、watchOS 和 tvOS 上處理基于時(shí)間的視聽(tīng)媒體。通過(guò)開(kāi)發(fā)所需的工具提供了強(qiáng)大的功能集,讓開(kāi)發(fā)者能夠基于蘋(píng)果平臺(tái)創(chuàng)建當(dāng)下最先進(jìn)的媒體應(yīng)用程序,其針對(duì)64位處理器設(shè)計(jì),充分利用了多核硬件優(yōu)勢(shì),會(huì)自動(dòng)提供硬件加速操作,確保大部分設(shè)備能以最佳性能運(yùn)行。

AVFoundation的播放都圍繞AVPlayer展開(kāi),AVPlayer是一個(gè)用來(lái)播放基于時(shí)間的視聽(tīng)媒體的控制器對(duì)象。支持播放從本地、分布下載或通過(guò)HTTP Live Streaing協(xié)議得到的流媒體,并在多種播放場(chǎng)景中播放這些資源。

http://aloenet.com.cn/news/35794.html

相關(guān)文章:

  • 漢中網(wǎng)站建設(shè)服務(wù)自媒體視頻剪輯培訓(xùn)班
  • 論壇網(wǎng)站用的虛擬主機(jī)深圳外貿(mào)網(wǎng)絡(luò)推廣渠道
  • 哪個(gè)網(wǎng)站有做車(chē)庫(kù)門(mén)的創(chuàng)建網(wǎng)站免費(fèi)注冊(cè)
  • b2b2c平臺(tái)網(wǎng)站建設(shè)廣州網(wǎng)站排名優(yōu)化公司
  • 李氏牛仔網(wǎng)站建設(shè)風(fēng)濟(jì)南網(wǎng)站建設(shè)方案
  • wordpress僅顯示標(biāo)題互聯(lián)網(wǎng)廣告優(yōu)化
  • 個(gè)人網(wǎng)站 不用備案朋友圈廣告
  • 百度做一個(gè)網(wǎng)站多少錢(qián)專業(yè)制作網(wǎng)頁(yè)的公司
  • o2o網(wǎng)站開(kāi)發(fā)框架長(zhǎng)春seo排名優(yōu)化
  • 東莞哪家做網(wǎng)站比較好北京網(wǎng)上推廣
  • 做有網(wǎng)被視頻網(wǎng)站有哪些銷售平臺(tái)軟件有哪些
  • 成都網(wǎng)站搭建公司哪家好阿里大數(shù)據(jù)分析平臺(tái)
  • 網(wǎng)站建設(shè)丨找王科杰專業(yè)好的seo網(wǎng)站
  • 怎樣做網(wǎng)站外鏈seo的中文意思
  • 怎么做才能發(fā)布網(wǎng)站網(wǎng)站域名購(gòu)買(mǎi)
  • 淘客網(wǎng)站是怎么做的中國(guó)seo關(guān)鍵詞優(yōu)化工具
  • 濟(jì)南做網(wǎng)站的公司電腦全自動(dòng)掛機(jī)賺錢(qián)
  • 公務(wù)員建設(shè)文化與道德網(wǎng)站營(yíng)銷網(wǎng)站優(yōu)化推廣
  • 廣西網(wǎng)站建設(shè)蘇州網(wǎng)站制作
  • 做傳銷網(wǎng)站違法嗎品牌推廣策略分析
  • 做自己的網(wǎng)站可以賺錢(qián)嗎市場(chǎng)推廣方案怎么寫(xiě)
  • 織夢(mèng)做的網(wǎng)站 xampp百度seo排名主要看啥
  • 做外貿(mào)開(kāi)通哪個(gè)網(wǎng)站好seo優(yōu)化排名易下拉用法
  • 淘寶客做軟件網(wǎng)站app廣州百度競(jìng)價(jià)托管
  • 做網(wǎng)站需要自備服務(wù)器嗎市場(chǎng)營(yíng)銷培訓(xùn)
  • 北京網(wǎng)站建設(shè) 優(yōu)化seo優(yōu)化專員
  • 做中醫(yī)藥網(wǎng)站有前景嗎山東企業(yè)網(wǎng)站建設(shè)
  • 網(wǎng)絡(luò)信息安全網(wǎng)站開(kāi)發(fā)教程網(wǎng)站權(quán)重查詢接口
  • 網(wǎng)站建設(shè)win2012百度如何發(fā)布信息推廣
  • 用訂制音樂(lè)網(wǎng)站做的音樂(lè)算原創(chuàng)嗎人工智能培訓(xùn)班收費(fèi)標(biāo)準(zhǔn)