移動開發(fā)(IOS) – UIKit框架

轉(zhuǎn)載:

http://docoder.com/%E7%A7%BB%E5%8A%A8%E5%BC%80%E5%8F%91ios-uikit%E6%A1%86%E6%9E%B6/#rd

1.UIView

1.1.所有 UI 控件都繼承自 UIView。

1.2.每一個 UIView 都是一個容器,可以容納其他 UIView。其中容器視圖被稱為父視圖,而被包含的視圖或者控件被成為子視圖或者子控件。

1.3.視圖對應(yīng)的文件通常是 storyboard 或者 xib 文件。在許多 iOS 應(yīng)用程序中,通常不必為視圖編寫任何代碼。

1.4.UIView 負責界面的顯示。

1.5.常用屬性

| superview | 獲得自己的父控件對象 |
| subviews | 獲得自己的所有子控件對象 |

一個視圖最多只能有一個父視圖,一個視圖可以有多個子視圖。

| frame | 控件所在矩形框的位置和尺寸(以父控件的左上角為坐標原點) |
| bounds | 控件所在矩形框的位置和尺寸(以自己左上角為坐標原點,所以bounds的x和y永遠為0) |
| center | 控件中點的位置(以父控件的左上角為坐標原點),通過center屬性設(shè)置視圖位置更加方便 |

用 frame 和 center 可以修改 UIView 的位置。
用 frame 和 bounds 可以修改 UIView 的尺寸。
通常,修改自身位置大小時使用 frame,而子視圖(控件)在設(shè)置位置時,會相對父視圖的 bounds 進行設(shè)置。

| tag | 控件的ID(標記),父控件可以通過tag來找到或區(qū)分子控件 |

tag 為一個整數(shù),并且兩個控件的 tag 默認為0,也可能相同。而在使用 tag 來找到或區(qū)分子控件時只會返回第一個與之相符的子控件。

| transform | 控件的形變屬性(可以設(shè)置旋轉(zhuǎn)角度、比例縮放、平移等屬性) |

UIView 一次只能應(yīng)用一個形變屬性
設(shè)置 transfrom 會改變 UIView 的 frame 屬性,但不會改變 bounds 屬性。
CGAffineTransformMakeRotate、CGAffineTransformMakeScale、CGAffineTransformMakeTranslation 相對 UIView 的初始狀態(tài)進行形變
CGAffineTransformRotate、CGAffineTransformScale、CGAffineTransformTranslation 相對 UIView 的當前狀態(tài)進行形變

1.6.動畫

1.6.1.UIView 封裝的簡單動畫效果

|

1

2

3

4

5

6

|

[UIView beginAnimations:``nil context:``nil``];

// 設(shè)置動畫持續(xù)時間

[UIView setAnimationDuration:.3];

// 需要動畫的代碼段

// ... ...

[UIView commitAnimations];

|

1.6.2.UIView 封裝的三個 block 動畫方法

|

1

2

3

4

5

6

|

//1

[UIView animateWithDuration:animations:]

//2

[UIView animateWithDuration:animations:completion:]

//3

[UIView animateWithDuration: delay: options: animations: completion:]

|

1.6.3.對比 beginAnimations 動畫的方式,block 動畫的優(yōu)勢:
可以在動畫完成時做一些其他的任務(wù)
可以設(shè)置動畫延遲及動畫效果選項
block 動畫支持嵌套

2.UIButton

2.1.實例化:

2.1.1.init方式:

|

1

|

UIButton *button = [[UIButton alloc] initWithFrame:rect];

|

2.1.2.類方法方式:

|

1

|

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];

|

其中按鈕類型枚舉:

| UIButtonTypeCustom | 按鈕的內(nèi)容需要自定義 |
| UIButtonTypeRoundedRect | 圓角矩形按鈕 |
| UIButtonTypeDetailDisclosure | 顯示明細按鈕 |
| UIButtonTypeInfoLight | 亮色信息按鈕,用于深色背景 |
| UIButtonTypeInfoDark | 深色信息按鈕,用戶淺色背景 |
| UIButtonTypeContactAdd | 添加按鈕 |

2.2.基本設(shè)置

2.2.1.設(shè)置文字

在設(shè)置按鈕文字時,需要指定文字對應(yīng)的按鈕狀態(tài):

|

1

2

3

4

|

//正常狀態(tài)下按鈕文字

[btn setTitle:``@"正常" forState:UIControlStateNormal];

//長按按鈕狀態(tài)下的按鈕文字

[btn setTitle:``@"長按" forState:UIControlStateHighlighted];

|

2.2.2.設(shè)置文字顏色

在設(shè)置按鈕文字顏色時,也需要指定文字對應(yīng)的按鈕狀態(tài):

|

1

2

|

[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];

[btn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];

|

2.2.3.設(shè)置背景顏色

|

1

|

[btn setBackgroundColor:[UIColor orangeColor]];

|

2.2.4.設(shè)置圖片及背景圖像

|

1

2

3

4

5

6

|

// 加載圖像

UIImage *image = [UIImage imageNamed:``@"sub_black_add.png"``];

// 設(shè)置按鈕圖像

[btn setImage:image forState:UIControlStateNormal];

// 設(shè)置按鈕背景圖像

[btn setBackgroundImage:image forState:UIControlStateNormal];

|

背景圖像會根據(jù)按鈕的尺寸拉伸,按鈕圖像會居中顯示在按鈕中央位置。
如果同時設(shè)置了按鈕的圖像和文字,按鈕區(qū)域足夠大,會并列顯示圖像和文字,如果區(qū)域不夠大,優(yōu)先顯示圖像。

2.3.設(shè)置按鈕點擊監(jiān)聽

|

1

2

|

// 設(shè)置按鈕點擊監(jiān)聽

[btn addTarget:``self action:``@selector``(tapButton) forControlEvents:UIControlEventTouchUpInside];

|

調(diào)用自定義方法需要使用 @selector 指令,按鈕事件最多只可以帶一個參數(shù)。

3.UILabel

3.1.實例化:

|

1

2

|

// 實例化 UILabel 并指定其邊框

UILabel *label = [[UILabel alloc]initWithFrame:rect];

|

3.2.基本設(shè)置

3.2.1.設(shè)置文本

|

1

|

[label setText:``@"Hello World"``];

|

3.2.2.設(shè)置字體和字體大小

|

1

|

[label setFont:[UIFont fontWithName:``@"Helvetica-Bold" size:40]];

|

3.2.3.設(shè)置背景色

|

1

|

[label setBackgroundColor:[UIColor greenColor]];

|

3.2.4.設(shè)置文本的顏色

|

1

|

[label setTextColor:[UIColor whiteColor]];

|

3.2.5.設(shè)置文本的陰影色彩和透明度

|

1

|

[label setShadowColor:[UIColor colorWithWhite:0.1f alpha:0.8f]];

|

3.2.6.設(shè)置陰影的偏移量

|

1

|

[label setShadowOffset:CGSizeMake(2.0f, 2.0f)];

|

3.2.7.設(shè)置文本的對齊方式

|

1

|

[label setTextAlignment:``NSTextAlignmentCenter``];

|

3.2.8.指定換行模式

|

1

|

[label setLineBreakMode:``NSLineBreakByWordWrapping``];``//按照單詞換行的方式處理

|

3.2.9.指定行數(shù),為0時沒有最大行數(shù)限制

|

1

|

[label setNumberOfLines:2];

|

4.UITextField

4.1.作用:供用戶輸入或編輯文本

4.2.text 屬性:獲得或設(shè)置文本框中的文字

4.3.使用文本框控件時的注意事項:

4.3.1.在輸入不同類型的文本時,需要注意鍵盤的類型。

4.3.2. 如果界面上有多個文本框供用戶輸入時,要注意回車鍵的設(shè)置,實現(xiàn)文本框由上至下的切換,切換到最后一個文本框,再按回車鍵時,調(diào)用對應(yīng)的確認按鈕的方法。

4.3.3.需要注意關(guān)閉鍵盤,關(guān)閉鍵盤有兩種方法:

|

1

2

3

4

|

//1

[``self``.view endEditing:``YES``];

//2

[textField resignFirstResponder];

|

4.3.4.要監(jiān)聽文本框的回車事件,需要設(shè)置文本框的delegate,同時讓視圖控制器遵從<UITextFieldDelegate>協(xié)議。

4.4.設(shè)置鍵盤和鍵盤上面的工具欄

|

1

2

3

4

|

// 設(shè)置日期文本的輸入鍵盤

[_dateText setInputView:datePickerView];

// 設(shè)置鍵盤上面的工具控件

[_dateText setInputAccessoryView:toolView];

|

4.5.常用代理方法:

|

1

2

3

4

5

6

7

8

9

10

11

|

// 當文本框開始獲得焦點的時候調(diào)用

- (``void``)textFieldDidBeginEditing:

// 當用戶失去焦點的時候調(diào)用

- (``void``)textFieldDidEndEditing:

// 在文本框準備聚焦的時候調(diào)用,返回NO代表不允許聚焦(編輯)

- (``BOOL``)textFieldShouldBeginEditing:

// 在文本框準備失去焦點(退出鍵盤)的時候調(diào)用,返回YES代表允許退出鍵盤

- (``BOOL``)textFieldShouldEndEditing:

// 在用戶每次輸入的時候都會調(diào)用,返回YES代表允許輸入

- (``BOOL``)textField:

shouldChangeCharactersInRange:replacementString:

|

5.UIImageView (圖像視圖)

5.1.作用:

專門用來顯示圖片的控件

5.2.基本設(shè)置

5.2.1.設(shè)置圖像

|

1

|

[``self``.imageView setImage:[UIImage imageNamed:``@"abc.png"``]];

|

5.2.2.設(shè)置顯示模式

|

1

2

|

//設(shè)置圖片居中顯示,并且保持原來寬高比

imageView.contentMode = UIViewContentModeScaleAspectFit;

|

5.3.UIImageView的序列幀動畫

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

5.3.2.屬性說明:

| animationImages | 要顯示的一組圖片序列 |
| animationDuration | 完整地顯示所有圖片所需的時間 |
| animationRepeatCount | 動畫的執(zhí)行次數(shù)(默認為0,代表無限循環(huán)) |

5.3.3.相關(guān)方法:

| – (void)startAnimating; | 開始動畫 |
| – (void)stopAnimating; | 停止動畫 |
| – (BOOL)isAnimating; | 是否正在運行動畫 |

6.UISlider (滑塊控件)

6.1.作用:

用來顯示進度值,并且可以手動修改進度值

6.2.基本設(shè)置

|

1

2

3

4

5

6

|

// 設(shè)置滑塊最大值

[slider setMaximumValue:15];

// 設(shè)置滑塊最小值

[slider setMinimumValue:0];

// 設(shè)置滑塊當前數(shù)值

[slider setValue:5];

|

6.3.事件監(jiān)聽

|

1

2

3

4

5

6

7

|

//監(jiān)聽 UISlider 的進度值改變,要使用 Value Changed 事件

//通過代碼為 UISlider 添加監(jiān)聽器:

[slider addTarget:``self action:``@selector``(sliderChange:) forControlEvents:UIControlEventValueChanged];

//當UISlider 的進度值發(fā)生改變時,會自動調(diào)用 self 的 sliderChange:方法,并且將 UISlide r作為第一個參數(shù)傳入

- (``void``) sliderChange:(UISlider *)slider

{

}

|

7.UISwitch (開關(guān)控件)

7.1.作用:開關(guān)

7.2.基本設(shè)置

|

1

2

3

4

|

//設(shè)置On或者Off

[mySwitch setOn:``YES``];

//判斷當前狀態(tài)

BOOL state = [mySwitch isOn];

|

7.3.事件監(jiān)聽
監(jiān)聽 UISwitch 的狀態(tài)改變,要使用 Value Changed 事件(可參照 UISlider 的使用)。

8.UIStepper (計數(shù)器控件)

8.1.作用:計數(shù)

8.2.基本設(shè)置與滑塊控件類似。

8.3.與滑塊控件的區(qū)別:

8.3.1.每按一次減號,value 就會自動減去一定的數(shù)值(數(shù)值大小由 stepValue 決定)。

8.3.2.每按一次加號,value 就會自動增加一定的數(shù)值(數(shù)值大小由 stepValue 決定)。

8.4.事件監(jiān)聽

監(jiān)聽 UISwitch 的狀態(tài)改變,要使用 Value Changed 事件(可參照 UISlider 的使用)。

9.UISegmentControl (選項卡控件)

9.1.作用:同一時刻只能選中一個標簽

9.2.基本設(shè)置

|

1

2

|

NSArray *items = @[``@"1列"``, @"2列"``, @"3列"``];

UISegmentedControl *control = [[UISegmentedControl alloc] initWithItems:items];

|

9.3.獲得當前被選中的標簽位置

|

1

|

int index = control.selectedSegmentIndex;

|

9.4.事件監(jiān)聽

監(jiān)聽 UISwitch 的狀態(tài)改變,要使用 Value Changed 事件(可參照 UISlider 的使用)。

10.UIScrollView

10.1.作用:

10.1.1.用于顯示超出應(yīng)用程序窗口大小的內(nèi)容

10.1.2.允許用戶通過拖動手勢滾動查看視圖中的內(nèi)容

10.1.3.允許用戶通過捏合手勢縮放視圖中的內(nèi)容

10.2.常用屬性:

| contentSize | 設(shè)置UIScrollView的滾動范圍 |
| contentOffset | UIScrollView當前滾動的位置 |
| contentInset | 增加滾動視圖四周的增加滾動范圍 |
| bounces | 是否有彈簧效果 |
| scrollEnabled | 是否能滾動 |
| showsHorizontalScrollIndicator | 是否顯示水平方向的滾動條 |
| showsVerticalScrollIndicator | 是否顯示垂直方向的滾動條 |
| indicatorStyle | 設(shè)定滾動條的樣式 |
| dragging | 是否正在被拖拽 |
| tracking | 按住手指還沒有開始拖動的時候值是YES,否則NO |
| decelerating | 是否正在減速 |
| zooming | 是否正在縮放 |

10.3.屬性說明

10.3.1.UIScrollView 的完整區(qū)域是在 contentSize 的四周增加 contentInset 設(shè)定的范圍

10.3.2.UIScrollView 顯示內(nèi)容的區(qū)域由其 frame 屬性決定

10.3.3.UIScrollView 顯示的內(nèi)容 由 contentOffset 相對 contentSize 的原點決定

10.4.ScrollView的手勢縮放步驟:

10.4.1.設(shè)置 UIScrollView 的 id<UISCrollViewDelegate> delegate 代理對象。

10.4.2.設(shè)置 minimumZoomScale:縮小的最小比例

10.4.3.設(shè)置 maximumZoomScale:放大的最大比例

10.4.4.讓代理對象實現(xiàn)以下方法,返回需要縮放的視圖控件

|

1

|

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView

|

與縮放相關(guān)的方法還包括:

|

1

2

3

4

|

// 正在縮放時調(diào)用的方法

- (``void``)scrollViewDidZoom:(UIScrollView *)scrollView

// 縮放完成時調(diào)用的方法

- (``void``)scrollViewDidEndZooming:(UIScrollView *)scrollView

|

10.4.5.ScrollView實現(xiàn)分頁效果

要實現(xiàn)分頁效果,將滾動視圖的 pagingEnabled 屬性設(shè)置為 YES 即可。設(shè)置該屬性后滾動視圖會被分割成多個獨立的頁面,用戶原本的滾動體驗會變成了頁面切換的效果。

11.UIPageControl (分頁控制控件)

11.1.要使用滾動視圖的分頁效果,通常會配合 UIPageControl 分頁控制控件,以增強分頁效果。

UIPageControl的頁數(shù)和UIScorllView中的實際頁數(shù)是分別處理的,二者之間不必一一對應(yīng)。

11.2.常用屬性:

| numberOfPages | 總頁數(shù) |
| currentPage | 當前的頁碼 |
| hidesForSinglePage | 當只有一頁的時候,是否要隱藏視圖 |
| currentPageIndicatorTintColor | 當前選中頁面標示的顏色 |
| pageIndicatorTintColor | 其他頁面標示的顏色 |

11.3.事件監(jiān)聽(監(jiān)聽頁面變化)

|

1

2

3

4

|

// 添加事件監(jiān)聽方法

[pageControl addTarget:``self action:``@selector``(pageChanged:) forControlEvents:UIControlEventValueChanged];

// 頁面變化調(diào)用方法

- (``void``)pageChanged:(UIPageControl *)pageControl

|

12.UIDatePicker

12.1.作用:方便用戶的日期選擇,并保證日期格式正確

12.2.實例化:

|

1

2

|

// 實例化日期控件,不用設(shè)置寬高,因為它的寬高是固定的

UIDatePicker *datePicker = [[UIDatePicker alloc]init];

|

12.3.基本設(shè)置

|

1

2

3

4

|

// 設(shè)置日期控件區(qū)域為簡體中文

[datePicker setLocale:[[``NSLocale alloc]initWithLocaleIdentifier:``@"zh_Hans_CN"``]];

// 設(shè)置日期控件格式

[datePicker setDatePickerMode:UIDatePickerModeDate];

|

12.4.事件監(jiān)聽

|

1

2

|

// 設(shè)定日期控件監(jiān)聽方法

[datePicker addTarget:``self action:``@selector``(dateValueChange:) forControlEvents:UIControlEventValueChanged];

|

13.UIPickerView (數(shù)據(jù)選擇視圖)

13.1.作用:負責從指定的數(shù)據(jù)源中選擇數(shù)據(jù)

13.2.要求:使用 PickerView 之前需要指定數(shù)據(jù)源

13.2.1.數(shù)據(jù)源負責計算 UIPickerView 有多少列、多少行數(shù)據(jù)

13.2.2.數(shù)據(jù)源須遵守 UIPickerViewDataSource 協(xié)議,數(shù)據(jù)源方法如下:

|

1

2

3

4

|

// 返回總的列數(shù)

- (``NSInteger``)numberOfComponentsInPickerView:

// 返回第component列的行數(shù)

- (``NSInteger``)pickerView:numberOfRowsInComponent:

|

13.2.3刷新數(shù)據(jù)方法:

|

1

|

[pickerView reloadComponent:1];

|

一旦調(diào)用了這個方法,就會重新給數(shù)據(jù)源發(fā)送消息計算這列的行數(shù)、重新給代理發(fā)送消息獲得這列的內(nèi)容。

13.3.代理

13.3.1.代理可以給 UIPickerView 提供具體的數(shù)據(jù)、監(jiān)聽 UIPickerView 的一些事件

13.3.2.代理必須遵守 UIPickerViewDelegate 協(xié)議,常用代理方法如下:

|

1

2

3

4

5

6

7

8

|

// 第component列第row行顯示什么字符串內(nèi)容

- (``NSString *)pickerView:titleForRow:forComponent:

// 每當選擇了新的一行就會調(diào)用

- (``void``)pickerView:didSelectRow:inComponent:

// 第component列第row行顯示什么樣的UIView,最后一個view參數(shù)是用來性能優(yōu)化的

- (UIView *)pickerView:viewForRow:forComponent:reusingView:

// 返回第component列每一行的高度

- (CGFloat)pickerView:rowHeightForComponent:

|

13.3.3.自定義 PickerView 時,需要指定顯示選擇指示器屬性:

|

1

|

pickerView.showsSelectionIndicator = YES``;

|

14.UITableView

14.1.作用:以垂直滾動方式顯示數(shù)據(jù)列表。

14.2.UITableView 的兩種內(nèi)置樣式:UITableViewStylePlain* 和 *UITableViewStyleGrouped 。

14.3.數(shù)據(jù)源 (dataSource) 和代理 (delegate)

14.3.1.UITableView 需要一個數(shù)據(jù)源(dataSource)來顯示數(shù)據(jù),UITableView 會向數(shù)據(jù)源查詢一共有多少行數(shù)據(jù)以及每一行顯示什么數(shù)據(jù)等。沒有設(shè)置數(shù)據(jù)源的 UITableView 只是個空殼。凡是遵守UITableViewDataSource 協(xié)議的 OC 對象,都可以是 UITableView 的數(shù)據(jù)源。

|

1

2

3

4

5

6

|

// 一共有多少組數(shù)據(jù)

- (``NSInteger``)numberOfSectionsInTableView:

// 每一組有多少行數(shù)據(jù)

- (``NSInteger``)tableView:numberOfRowsInSection:

// 每一行具體顯示的內(nèi)容

- (UITableViewCell *)tableView:cellForRowAtIndexPath:

|

14.3.2.通常都要為 UITableView 設(shè)置代理對象(delegate),以便在 UITableView 觸發(fā)一下事件時做出相應(yīng)的處理,比如選中了某一行。凡是遵守了 UITableViewDelegate 協(xié)議的 OC 對象,都可以是 UITableView 的代理對象。

|

1

2

3

4

|

// 選中了某一行

(``void``)tableView:didSelectRowAtIndexPath:

// 每一行有多高

- (CGFloat)tableView:heightForRowAtIndexPath:

|

14.3.3.通常情況下,會讓控制器充當 UITableView 的 dataSource 和 delegate。

14.3.4.UITableView 的每一行都是一個 UITableViewCell,通過 dataSource 的tableView:cellForRowAtIndexPath: 方法來初始化每一行。

14.3.5.UITableViewCell是UIView的子類,內(nèi)部有個默認的子視圖:contentView。

14.3.6.contentView是UITableViewCell顯示內(nèi)容的父視圖,并負責顯示一些輔助指示視圖。

14.3.7.輔助指示視圖的作用是顯示一個表示動作的圖標,可以通過設(shè)置UITableViewCell的accessoryType來顯示,默認是UITableViewCellAccessoryNone,即不顯示輔助指示視圖 ,其他值如為

: UITableViewCellAccessoryDisclosureIndicator , UITableViewCellAccessoryDetailDisclosureButton和 UITableViewCellAccessoryCheckmark。

14.3.8.contentView下默認有3個子視圖,其中的2個是UILabel,通過textLabel和detailTextLabel屬性訪問,第3個是UIImageView,通過imageView屬性訪問。

14.3.9.UITableViewCell的UITableViewCellStyle,用于決定使用contentView的哪些子視圖,以及這些子視圖在contentView中的位置。有:UITableViewCellStyleDefault , UITableViewCellStyleSubtitle, UITableViewCellStyleValue1 和 UITableViewCellStyleValue2。

14.4.UITableViewCell對象的重用原理:

14.4.1.當滾動列表時,部分 UITableViewCell 會移出窗口,UITableView 會將窗口外的 UITableViewCell 放入一個對象池中,等待重用。當 UITableView 要求 dataSource 返回 UITableViewCell 時,dataSource 會先查看這個對象池,如果池中有未使用的 UITableViewCell,dataSource 會用新的數(shù)據(jù)配置這個 UITableViewCell,然后返回給 UITableView,重新顯示到窗口中,從而避免創(chuàng)建新對象。

14.4.2.UITableViewCell有個NSString *reuseIdentifier屬性,可以在初始化UITableViewCell的時候傳入一個特定的字符串標識來設(shè)置reuseIdentifier(一般用UITableViewCell的類名)。當UITableView要求dataSource返回UITableViewCell時,先通過一個字符串標識到對象池中查找對應(yīng)類型的UITableViewCell對象,如果有,就重用,如果沒有,就傳入這個字符串標識來初始化一個UITableViewCell對象。

14.5.UITableView的編輯模式

14.5.1.UITableView屬有個editing性,當設(shè)置為YES時,可以進入編輯模式。在編輯模式下,可以管理表格中的行,比如改變行的排列順序、增加行、刪除行,但不能修改行的內(nèi)容。

14.5.2.開啟編輯模式的方法:

|

1

2

|

@property``(``nonatomic``,getter=isEditing) BOOL editing;

- (``void``)setEditing:(``BOOL``)editing animated:(``BOOL``)animated;

|

14.5.3.在UITableView中刪除或添加行:

|

1

2

3

4

5

6

|

//1\. 開啟表格的編輯模式

//2\. 實現(xiàn)UITableViewDataSource的方法:

- (``void``)tableView:commitEditingStyle:forRowAtIndexPath:

//3\. 實現(xiàn)UITableViewDelegate的方法:

- (UITableViewCellEditingStyle)tableView: editingStyleForRowAtIndexPath:

//注意:如果不實現(xiàn)該方法,默認將編輯模式視為刪除

|

14.5.4.移動UITableView的行:

|

1

2

3

4

|

//1\. 開啟表格的編輯模式

//2\. 實現(xiàn)UITableViewDataSource的方法:

- (``void``)tableView:moveRowAtIndexPath:toIndexPath:

注意:只要實現(xiàn)了該方法,即可實現(xiàn)表格移動

|

14.6.四種刷新表格數(shù)據(jù)的方法:

|

1

2

3

4

5

6

7

8

|

// 新增表格數(shù)據(jù)

[tableView insertRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop];

// 刪除表格數(shù)據(jù)

[tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationRight];

// 局部刷新指定的行

[tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationMiddle];

// 刷新全部表格數(shù)據(jù),如果能夠準確確定被修改的數(shù)據(jù)行,就不要用此方法

[tableView reloadData];

|

14.7.常用屬性

14.7.1.分隔線屬性

| separatorStyle | 分隔線樣式 |
| separatorColor | 分隔線顏色 |

14.7.2.選中屬性

| allowsSelection | 允許選中 |
| allowsMultipleSelection | 允許多選 |

14.7.3.行數(shù)

| indexPathsForSelectedRows | 當前選中行數(shù) |
| indexPathsForVisibleRows | 當前可見行數(shù) |

14.7.4.背景

| backgroundView | 背景視圖 |
| selectedBackgroundView | 選中時的背景視圖 |

14.7.5.UITableViewCell的selectionStyle屬性可設(shè)置被選中時的背景顏色:

| UITableViewCellSelectionStyleNone | 沒有顏色 |
| UITableViewCellSelectionStyleBlue | 藍色(默認) |
| UITableViewCellSelectionStyleGray | 灰色 |

14.8.自定義UITableViewCell

14.8.1.有三種方式自定義單元格:XIB , Storyboard 和 代碼。

14.8.2.通過XIB或者Storyboard自定義單元格時,需要指定單元格的可重用標示符。

14.8.3.如果使用XIB方式,需要在viewDidload方法中,注冊XIB文件:

|

1

2

|

UINib *nib = [UINib nibWithNibName:``@"cellName" bundle:[``NSBundle mainBundle]];

[``self``.tableView registerNib:nib forCellReuseIdentifier:``@"cellID"``];

|

14.8.4.在Storyboard中直接自定義單元格會注冊單元格原型。

14.8.5.用代碼方式自定義單元格需要注冊類:

|

1

|

[tableView registerClass:[MyCell class``] forCellReuseIdentifier:CellIdentifier];

|

14.8.6.注冊單元格后,可以直接:

|

1

|

tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

|

14.9.靜態(tài)表格

14.9.1.可以等同于 UIViewController 處理。

14.9.2.靜態(tài)表格必須嵌入在 UITableViewController 中使用。

14.9.3.可以通過 cellForRowAtIndexPath 方法獲取到用戶當前選中的單元格。

14.9.4.應(yīng)用場合:針對不需要發(fā)生變化的設(shè)置或者關(guān)于界面的表格視圖布局。

14.9.5.靜態(tài)表格無需優(yōu)化處理。

14.10.提高性能建議:

14.10.1.使用可重用cell:申請內(nèi)存是需要時間,特別是在一段時間內(nèi)頻繁的申請內(nèi)存將會造成很大的開銷,而且上tebleView中cell大部分情況下布局都是一樣的,可以通過回收重用機制來提高性能。

14.10.2.避免content的重新布局:盡量避免在重用cell時候,對cell的內(nèi)容重新布局,一般情況下,應(yīng)該在創(chuàng)建cell的時候就將cell布局好。

14.10.3.使用不透明的subView:在定制cell的時,將要添加的subView設(shè)置成不透明的會大大減少多個view層疊加時渲染所需要的時間。

15.UISearchBar

15.1.其本身不做任何搜索,而僅是提供一個基本的iOS搜索欄界面

15.2.UISearchBar類用delegate協(xié)議的方式來告訴應(yīng)用程序的其他部分,用戶正在搜索欄中做什么

15.3.程序員需要自己編寫對比字符串和過濾搜索的方法

15.4.實際應(yīng)用中需要使用Search Bar and Search Display Controller

15.5.常用屬性

| Text | 設(shè)置出現(xiàn)在搜索欄中的默認字符串,如果需要指定默認搜索內(nèi)容時使用 |
| Placeholder | 在搜索欄沒有添入任何字符串時,一般會顯示一串灰色的字符來提示用戶輸入搜索信息 |
| Prompt | 屬性值會出現(xiàn)在搜索欄上方。對于有復(fù)雜搜索功能的程序,用戶可能需要一些指導(dǎo)信息 |
| Style & Tint | 設(shè)置搜索欄的樣式和顏色。建議使用和UINavigationBar上同樣的設(shè)置 |
| Show Search Results Button | 如果選中此選項,搜索欄右邊會出現(xiàn)一個灰色按鈕??梢杂脕盹@示最近幾次的搜索,或者上次搜索的結(jié)果,通過Search Bar的代理方法可以控制該按鈕的行為 |
| Show Bookmarks Button | 如果選中此選項,搜索欄右邊會出現(xiàn)一個標準的藍色書簽按鈕。用戶可以調(diào)出他們儲存的書簽,通過Search Bar的代理方法可以控制該按鈕的行為 |
| Show Cancel Button | 如果選中此選項,搜索欄右邊會出現(xiàn)一個標準的取消按鈕,讓用戶取消搜索。初始不要選中此選項,因為當用戶在搜索欄中輸入內(nèi)容后,該按鈕會自動出現(xiàn) |
| Shows Scope Bar(顯示范圍欄) & Scope Titles(范圍標題) | 幫助用戶在指定范圍內(nèi)進行搜索,以縮小搜索范圍 |
| Capitalize(大小寫)、Correction(自動糾錯)、Keyboard(鍵盤) | 與UITextField的屬性相同,用于輔助用戶輸入 |
| | |

16.UIWebView

16.1.是 iOS 內(nèi)置的瀏覽器控件,可以瀏覽網(wǎng)頁、打開文檔等,能夠加載 html/htm、pdf、docx、txt等格式的文件,系統(tǒng)自帶的Safari瀏覽器就是通過 UIWebView 實現(xiàn)的。

16.2.常用加載方法: loadRequest: , loadHTMLString:baseURL: , loadData:MIMEType:textEncodingName:baseURL: 。

|

1

2

3

4

5

6

7

8

|

// 使用URL字符串替代URL文本框

[_urlText setText:[url absoluteString]];

// 定義請求

NSURLRequest *request = [``NSURLRequest requestWithURL:url];

// 設(shè)置數(shù)據(jù)檢測類型

[_webView setDataDetectorTypes:UIDataDetectorTypeAll];

// 加載請求

[_webView loadRequest:request];

|

|

1

2

3

4

5

6

7

|

// 測試加載HTML字符串

NSString *html = @"<html><head><title>Hello</title></head><body><h1>Hello Docoder</h1></body></html>"``;

[_webView loadHTMLString:html baseURL:``nil``];

// 測試加載部分HTML字符串,不需要顯示整個網(wǎng)頁內(nèi)容時,通常使用此方法

NSString *partHtml = @"<h1>Hello Docoder</h1>"``;

[_webView loadHTMLString:partHtml baseURL:``nil``];

|

|

1

2

3

4

5

6

7

8

|

// 測試加載本地 PDF,需要指定 MIMETYPE

[_webView loadData:[``NSData dataWithContentsOfFile:dataPath] MIMEType:``@"application/pdf" textEncodingName:``@"UTF-8" baseURL:``nil``];

// 測試加載本地文本文件,需要指定 MIMETYPE

[_webView loadData:[``NSData dataWithContentsOfFile:dataPath] MIMEType:``@"text/plain" textEncodingName:``@"UTF-8" baseURL:``nil``];

// 測試加載本地HTML文件,需要指定 MIMETYPE

//baseURL是基準URL,程序要用到其他資源的位置

NSURL *baseURL = [``NSURL fileURLWithPath:[[``NSBundle mainBundle]resourcePath] isDirectory:``YES``];

[_webView loadData:[``NSData dataWithContentsOfFile:dataPath] MIMEType:``@"text/html" textEncodingName:``@"UTF-8" baseURL:baseURL];

|

16.3.常用導(dǎo)航方法:

| goBack | 回退 |
| goForward | 前進 |
| reload | 重載 |
| stopLoading | 取消載入內(nèi)容 |

16.4.常用屬性:

| scalespageToFit | 自動對頁面進行縮放以適應(yīng)屏幕 |
| dataDetectorTypes | 設(shè)定電話號碼、網(wǎng)址、電子郵件和日期等文字變?yōu)殒溄游淖?|

17.UIApplication

17.1.UIApplicationMain

在main.m的main函數(shù)中執(zhí)行了UIApplicationMain這個方法,這是ios程序的入口點:

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

|

/*

* argc、argv:ISO C標準main函數(shù)的參數(shù),直接傳遞給UIApplicationMain進行相關(guān)處理即可

* principalClassName:指定應(yīng)用程序類,該類必須是UIApplication或其子類。如果為nil,則用UIApplication類作為默認值

* delegateClassName:指定應(yīng)用程序類的代理類,該類必須遵守UIApplicationDelegate協(xié)議

*/

int UIApplicationMain(``int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);

/*

* 方法說明:

* 1) 由第3個參數(shù)創(chuàng)建一個UIApplication對象,一個程序?qū)?yīng)一個UIApplication對象(單例),UIApplication對象是程序的象征

* 2) 由第4個參數(shù)創(chuàng)建一個UIApplication的delegate對象

* 3) 開啟一個消息循環(huán)(不斷地監(jiān)聽地一些系統(tǒng)事件)

* 4) 監(jiān)聽到相應(yīng)的事件后,就會給代理發(fā)送相應(yīng)的消息,應(yīng)用程序啟動完成后,首先會調(diào)用代理對象的 application:didFinishLaunchingWithOptions: 方法

*/

UIApplicationMain(argc, argv, nil``, NSStringFromClass``([AppDelegate class``]));

|

17.2. UIApplication 說明

17.2.2.UIApplication 是應(yīng)用程序的核心,每一個程序在運行期必須有 UIApplication (或子類)的一個實例(有且僅有一個),通過 [UIApplication sharedApplication] 可以得到這個單例實例的指針

17.2.2.UIApplication 幫助管理應(yīng)用程序的生命周期,而它通過 delegate 來履行這個任務(wù)

17.2.4.UIApplication 可以接收事件,把所有用戶事件都放入隊列,逐個處理,它會發(fā)送當前事件給一個合適的目標控件進行處理。它還將部分事件轉(zhuǎn)給 delegate 對象來處理,delegate 可處理的事件包括:應(yīng)用程序的生命周期事件(如程序啟動和關(guān)閉)、系統(tǒng)事件(如來電)。

17.2.5.在開發(fā)過程中,UIApplication 是一個非常重要的全局對象。但在實際編程中我們并不直接和UIApplication 對象打交道,而是和其代理打交道,它的代理必須遵守 UIApplicationDelegate 協(xié)議,代理提供了相關(guān)的生命周期方法來處理應(yīng)用程序的系統(tǒng)事件

17.2.6.IOS 設(shè)備的內(nèi)存極其有限,如果為 app 分配了太多內(nèi)存,操作系統(tǒng)會終止 app 的運行,在 UIApplication 接收到這個事件后它會調(diào)用代理的 applicationDidReceiveMemoryWarning 方法,代理在這個方法內(nèi)可以進行釋放內(nèi)存的操作以防止操作系統(tǒng)強制終止應(yīng)用程序的運行

17.3.UIApplicationDelegate

17.3.1.ios并不是多任務(wù)的操作系統(tǒng),所以app很容易受到打擾。比如一個來電可能導(dǎo)致app失去焦點,如果這個時候接聽了電話,那么app會自動終止運行

17.3.2.還有很多其它類似的事件會導(dǎo)致 app 失去焦點:

app 失去焦點前會調(diào)用代理的applicationWillResignActive ;

app 再次獲取焦點時會調(diào)用代理的 applicationDidBecomeActive ;

在運行 app 時鎖屏?xí){(diào)用代理的 applicationWillResignActive;

當屏幕被解鎖時,會調(diào)用代理的applicationDidBecomeActive。

17.3.3. 應(yīng)用程序成為激活狀態(tài)后,才可以與用戶進行交互。

17.3.4. 如果要做保存游戲狀態(tài)之類操作,應(yīng)該在注銷激活方法中處理,
因為用戶可能會雙擊home鍵,打開任務(wù)欄,此時應(yīng)用程序不會退出到后臺!

17.3.5. 如果要做恢復(fù)游戲狀態(tài)之類的操作,應(yīng)該在成為激活方法中處理,
因為用戶可能是從任務(wù)欄中返回的。

17.3.6. 如果應(yīng)用程序運行過程中,內(nèi)存或其他原因,程序被系統(tǒng)強行退出時,會調(diào)用Terminate方法,
開發(fā)者,可以再此記錄應(yīng)用程序被退出前的狀態(tài),以便改進系統(tǒng)

17.3.7. 應(yīng)用程序退出到后臺后,未必會是休眠狀態(tài),有可能會繼續(xù)運行,例如:微博、QQ、音樂播放器等軟件

17.3.8. 在UIKit開發(fā)中,通常不用在delegate中寫內(nèi)存警告方法,直接在ViewController中進行處理即可。

17.4.應(yīng)用程序的完整啟動過程

17.4.1.點擊程序圖標

17.4.2.執(zhí)行main函數(shù)

17.4.3.執(zhí)行UIApplicationMain函數(shù)

17.4.4.創(chuàng)建UIApplication對象、UIApplication的delegate對象

17.4.5.開啟事件循環(huán)監(jiān)聽系統(tǒng)事件

17.4.6.程序加載完畢后調(diào)用 delegate 對象的 application:didFinishLaunchingWithOptions: 方法:創(chuàng)建窗口UIWindow對象;創(chuàng)建控制器對象;設(shè)置窗口的根控制器;讓窗口成為主窗口、并且可見。

17.5.UIApplication 常用方法:

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

|

// 設(shè)置圖標右上角顯示的數(shù)字

[app setApplicationIconBadgeNumber:10];

// 顯示聯(lián)網(wǎng)狀態(tài)的提示,一般有網(wǎng)絡(luò)請求時,會自動顯示

[app setNetworkActivityIndicatorVisible:``YES``];

// 打開一個URL

// 在iOS中,很多東西都可以通過URL來訪問,例如:電話、短信、電子郵件等

// 比如:

// 打開網(wǎng)站

NSURL *url = [``NSURL URLWithString:``@"[http://www.baidu.com](http://www.baidu.com/)"``];

[app openURL:url];

// 電話會直接呼出

NSURL *url = [``NSURL URLWithString:``@"[tel://10010](tel://10010)"``];

[app openURL:url];

// 會跳出短信發(fā)送界面,等待用戶編輯并發(fā)送短信

NSURL *url = [``NSURL URLWithString:``@"[sms://10010](sms://10010)"``];

[app openURL:url];

|

18.UIWindow

18.1.UIWindow是一種特殊的UIView,通常在一個app中只會有一個UIWindow,但可以手動創(chuàng)建多個UIWindow

18.2.UIWindow的主要作用:

18.2.1.提供一個區(qū)域來顯示視圖

18.2.2.將事件分發(fā)給視圖

18.2.3.與UIViewController協(xié)同工作,方便完成設(shè)備方向旋轉(zhuǎn)的支持

18.3.將UIView添加到UIWindow中兩種常見方式:

18.3.1.addSubview:直接將 UIView 添加到 UIWindow 中,程序負責維護 UIView 的生命周期以及刷新,但并不會理會 UIView 對應(yīng)的 UIViewController

18.3.2.setRootViewController:自動將 UIViewController 對應(yīng)的 UIView 添加到 UIWindow 中,同時負責維護 UIViewController 和 UIView 的生命周期

18.4.UIWindow常用方法:

18.4.1.makeKeyAndVisible: 讓當前 UIWindow 變成 keyWindow,并顯示出來

18.4.2.makeKeyWindow:讓當前 UIWindow 變成 keyWindow

19.UIViewController

19.1.UIViewController 的作用:

19.1.1.創(chuàng)建/銷毀自己的 UIView

19.1.2.顯示/隱藏 UIView

19.1.3.處理 UIView 和用戶之間的交互(事件處理)。

19.2.每個 UIViewController 默認都有一個 UIView 屬性。

19.3.UIViewController 負責界面上元素及內(nèi)容的控制與調(diào)度。

19.4.“設(shè)置”應(yīng)用中的界面顯示過程如下:

19.4.1.創(chuàng)建一個 UIViewController

19.4.2.由 UIViewController 創(chuàng)建自己的 UIView(懶加載)

19.4.3.把 UIView 顯示到用戶眼前

19.4.4.UIViewController 監(jiān)聽并處理 UIView的事件

19.5.loadView 方法

19.5.1.視圖控制器的view懶加載(延遲加載),在使用到view時,才調(diào)用控制器的loadView方法加載view

19.5.2.loadView 加載 view 的默認過程(UIViewController的默認實現(xiàn)):

如果nibName有值,就會加載對應(yīng)的xib文件來創(chuàng)建view,如果nibName沒有值,優(yōu)先加載同名View.xib文件來創(chuàng)建view,再加載同名ViewController.xib文件來創(chuàng)建view,如果沒有找到上面所述的xib文件,就會用代碼創(chuàng)建一個透明的view。

19.5.3.loadView 方法主要用于處理以代碼的方式實現(xiàn)視圖界面

19.5.4.如果使用storyBoard或者xib方式,不建議重寫loadView方法。

19.5.5.在loadView方法中,不應(yīng)該調(diào)用super loadView方法。

20.UIImagePickerController

20.1.使用 UIImagePickerController 可以選擇照片。

20.2.照片的來源 UIImagePickerControllerSourceType 包括:照片庫、照相機、保存的照片。

20.3.使用步驟:

20.3.1. 判斷照片來源是否可用

20.3.2. 實例化照片選擇控制器

20.3.3. 設(shè)置照片源

20.3.4. 設(shè)置是否允許編輯

20.3.5. 設(shè)置代理

20.3.6. 遵循協(xié)議

20.3.7. 顯示照片選擇控制器

20.4.照片選擇代理方法

20.4.1.通過代理方法的 didFinishPickingMediaWithInfo 字典可以獲取選中的照片圖像

20.4.2.關(guān)閉照片選擇控制器

20.4.3.保存選中的圖像

21.三種創(chuàng)建應(yīng)用程序方式小結(jié)

21.1.使用代碼方式創(chuàng)建應(yīng)用程序

21.1.1.在loadView方法中編寫代碼,初始化視圖控件

21.1.2.在viewDidLoad方法中做數(shù)據(jù)處理

21.2.使用XIB方式創(chuàng)建應(yīng)用程序

21.2.1.界面設(shè)計工作交由XIB文件負責

21.2.2.在viewDidLoad方法中做數(shù)據(jù)處理

21.2.3.XIB可以設(shè)置一組平行關(guān)系的視圖/控制器數(shù)組,使用靈活,量級較輕

21.3.使用StoryBoard方式創(chuàng)建應(yīng)用程序

21.3.1.界面設(shè)計工作交由StoryBoard負責

21.3.2.在viewDidLoad方法中做數(shù)據(jù)處理

21.3.3.StoryBoard主要為了方便多視圖控制器之間的切換,量級較重

22.多控制器切換

22.1.視圖控制器常見的切換方式:

22.1.1.Tabbar 選項卡:以 UITabbarController 為容器,以平行的方式是管理子視圖控制器。

22.1.2.Push 推送:以 UINavigationController 為容器,以棧的形式管理子視圖控制器。

22.1.3.Modal 模態(tài):以模態(tài)窗口的方式顯示新的視圖控制器,新視圖控制器關(guān)閉前,用戶無法與原控制器進行交互。

22.2.容器

22.2.1.容器負責展示一個或者多個 ViewController,并管理這些ViewController的生命周期。

22.2.2.大部分容器本身也是一個 ViewController,被容器管理的這些控制器可以稱為容器的子控制器 ( childViewController ),而容器可以被稱為父控制器 ( parentViewController )。

22.2.3.也有極少數(shù)容器不是 ViewController,比如 UIPopoverController,其繼承于 NSObject。(注:UIPopoverController 只能在iPad中使用)

22.2.4.容器可以添加、移除或切換 childViewController。

22.2.5.容器持有所有 childViewController 的實例(一般存在 NSArray 中)。

22.2.6.容器負責 childViewController 的視圖生命周期方法的調(diào)用 : viewWillAppear, viewDidAppear, viewWillDisaapper, viewDidDisappear, 旋轉(zhuǎn)事件等。

22.3.segue 對象的生命周期

22.3.1創(chuàng)建目標視圖控制器。

22.3.2.創(chuàng)建 segue 對象并調(diào)用它的 initWithIdentifier:source:destination: 方法,其中的標示符是在 Interface Builder 中指定的唯一標示字符串,另外兩個參數(shù)分別對應(yīng)箭頭的起始控制器和目標控制器。

22.3.3.調(diào)用源視圖控制器的 prepareForSegue:sender: 方法。

22.3.4.調(diào)用 segue 對象的 perform 方法,負責將目標視圖控制器推送到屏幕。

22.3.5.釋放 segue 對象。

22.4.UITabbarController 和 UINavigationController 結(jié)合使用時,要先平行、再層次。

22.5.多視圖控制器跳轉(zhuǎn)方法:

22.5.1.Model:

打開:presentViewController:animated:completion:
關(guān)閉:dismissViewControllerAnimated:completion:

22.5.2.Push:

打開:pushViewController:animated:
關(guān)閉:popViewControllerAnimated:

22.5.3.Segue:

即可用于Modal亦可用于Push。
如果在打開目標控制器前需要做額外的處理,可以使用performSegueWithIdentifier:sender:方法。

23.UITabbarController

23.1.常用屬性:

| title | 標題 |
| image | 圖像(需要打開alpha通道,32*32以下,PNG格式) |
| badgeValue | 右上角的圖標 |
| viewControllers | 所有子視圖控制器 |

23.2.tabBarController在實例化時會加載其所有子視圖控制器

24.UINavigationController


24.1.以棧的形式管理子視圖控制器,只顯示棧頂?shù)囊晥D。

24.2.常用屬性:

| childViewControllers | 子視圖控制器 |
| title | 標題 |
| backBarButtonItem | 返回按鈕 |
| leftBarButtonItem | 左側(cè)按鈕 |
| rightBarButtonItem | 右側(cè)按鈕 |

24.3.常用方法:

| pushViewController | 將指定視圖控制器壓入棧頂 |
| popViewControllerAnimated | 將當前視圖控制器從棧中彈出 |

25.觸摸事件

25.1.UIKit可識別三種類型的輸入事件:觸摸事件、運動(加速計)事件、遠程控制事件。

25.2.UIEvent

25.2.1.iOS 中許多事件對象都是 UIEvent 類的實例,記錄事件產(chǎn)生的時刻和類型。

25.2.2.UIEvent 類事件類型的 enum 常量:

|

1

2

3

4

5

|

typedef NS_ENUM``(``NSInteger``, UIEventType) {

UIEventTypeTouches,

UIEventTypeMotion,

UIEventTypeRemoteControl,

};

|

25.2.3.由 UIEvent 對象的 type 屬性可以獲取事件的類型。

25.3.響應(yīng)者對象

25.3.1.在 iOS 中只有繼承了 UIResponder 的對象才能接收并處理事件。我們稱之為“響應(yīng)者對象”。

25.3.2.UIApplication、 UIViewController、 UIView 都繼承自 UIResponder,因此它們都是響應(yīng)者對象,都能夠接收并處理事件。

25.4.觸摸事件的處理

25.4.1.UIView(所有UIKit控件均繼承自 UIView )是 UIResponder 的子類,可以覆蓋下列4個方法處理不同的觸摸事件:

|

1

2

3

4

5

6

7

8

9

10

11

|

//1\. 一根或者多根手指開始觸摸屏幕(在一次觸摸事件中,只會調(diào)用一次)

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

//2.一根或者多根手指在屏幕上移動(隨著手指的移動,會持續(xù)調(diào)用該方法)

- (``void``)touchesMoved:(``NSSet *)touches withEvent:(UIEvent *)event

//3.一根或者多根手指離開屏幕(在一次觸摸事件中,只會調(diào)用一次)

//如果要調(diào)整控件的位置,可以利用 locationInView 和 previousLocationInView 計算移動差值即可

- (``void``)touchesEnded:(``NSSet *)touches withEvent:(UIEvent *)event

//4.觸摸結(jié)束前,某個系統(tǒng)事件(例如電話呼入)會打斷觸摸過程

- (``void``)touchesCancelled:(``NSSet *)touches withEvent:(UIEvent *)event

//注意:如果希望用戶手指按下屏幕,就立刻做出反應(yīng),使用touchesBegan;如果希望用戶手指離開屏幕,才做出反應(yīng),使用touchesEnded;通常情況下,應(yīng)該使用touchesBegan。

|

上述4個方法都有個 UIEvent 的參數(shù),通過 UIEvent 可以得到事件的類型和產(chǎn)生時間,以及當前處于活動狀態(tài)的所有觸摸操作。但是,通常會使用 UITouch 對象而不是 UIEvent 對象來處理觸摸事件。

25.4.2.當用戶觸摸屏幕時,系統(tǒng)會創(chuàng)建一個 UITouch 實例,并將該對象和接觸屏幕的那根手指關(guān)聯(lián)。 UITouch 保存著手指在屏幕上觸摸的位置。當手指移動時,系統(tǒng)會更新同一個 UITouch 對象,使之能夠一直保存該手指在屏幕上的當前位置。當手指離開屏幕時,系統(tǒng)會取消相應(yīng)的 UITouch 對象。

25.4.3.UITouch對象還會保存一些其他信息,比如,手指的前一個位置、手指按下屏幕的次數(shù)(tapCount, 可以用來判斷單擊和雙擊事件)。

25.4.4.因為可以有多根手指同時觸發(fā)同一個事件,所以傳給視圖的是一組 UITouch 對象,保存在 NSSet 中,例如:如果兩根手指同時觸摸某個視圖,那么 touchesBegan:withEvent: 的第一個參數(shù)是包含兩個 UITouch 實例的 NSSet 對象;如果這兩根手指一前一后分開觸摸同一個視圖,那么視圖會收到兩個獨立的 touchesBegan:withEvent: 消息,并且每個 NSSet 對象中只包含一個 UITouch 對象。因此,根據(jù) NSSet 中UITouch 的個數(shù)可以判斷出是單點觸摸還是多點觸摸。

25.4.5.按照響應(yīng)者鏈順序遞歸查找最先處理事件的UIView,重寫hitTest:withEvent:方法可以攔截觸摸事件。

25.5.UITouch

25.5.1.屬性

| window | 觸摸產(chǎn)生時所處的窗口。由于窗口可能發(fā)生變化,當前所在的窗口不一定是最開始的窗口 |
| view | 觸摸產(chǎn)生時所處的視圖。由于視圖可能發(fā)生變化,當前視圖也不一定時最初的視圖 |
| tapCount | 點按操作和鼠標的單擊操作類似,tapCount表示短時間內(nèi)點按屏幕的次數(shù)。因此可以根據(jù)tapCount判斷單擊、雙擊或更多的點按 |
| timestamp | 時間戳記錄了觸摸事件產(chǎn)生或變化時的時間,單位是秒 |
| phase | 觸摸事件在屏幕上有一個周期,即觸摸開始、觸摸點移動、觸摸結(jié)束,還有中途取消。通過phase可以查看當前觸摸事件在一個周期中所處的狀態(tài)。phase是UITouchPhase類型的,是一個枚舉配型,包含:
UITouchPhaseBegan(觸摸開始)
UITouchPhaseMoved(接觸點移動)
UITouchPhaseStationary(接觸點無移動)
UITouchPhaseEnded(觸摸結(jié)束)
UITouchPhaseCancelled(觸摸取消) |

25.5.2.成員函數(shù)

| – (CGPoint)locationInView:(UIView *)view: | 返回一個CGPoint類型的值,表示觸摸在view這個視圖上的位置,這里返回的位置是針對view的坐標系的。調(diào)用時傳入的view參數(shù)為空的話,返回的時觸摸點在整個窗口的位置 |
| – (CGPoint)previousLocationInView:(UIView *)view: | 該方法記錄了前一個坐標值,函數(shù)返回也是一個CGPoint類型的值, 表示觸摸在view這個視圖上的位置,這里返回的位置是針對view的坐標系的。調(diào)用時傳入的view參數(shù)為空的話,返回的時觸摸點在整個窗口的位置 |

25.6.觸摸事件的傳遞

25.6.1.發(fā)生觸摸事件后,系統(tǒng)會將該事件加入到一個由UIApplication管理的事件隊列中

25.6.2.UIApplication會從事件隊列中取出最前面的事件并將其分發(fā)以便處理,通常,先發(fā)送事件給應(yīng)用程序的主窗口

25.6.3.主窗口會調(diào)用hitTest:withEvent:方法在視圖繼承樹中找到一個最合適的子視圖來處理觸摸事件,該子視圖即為hit-test視圖,如果hit-test視圖不處理收到的事件消息,UIKit則將事件轉(zhuǎn)發(fā)到響應(yīng)者鏈中的下一個響應(yīng)者,看其是否能對該消息進行處理

25.7.響應(yīng)者鏈

響應(yīng)者鏈條,是通過遞歸構(gòu)成的一組UIResponder對象的鏈式序列。響應(yīng)者鏈事件處理過程為:

25.7.1.如果hit-test視圖的控制器存在,就傳遞給控制器;如果控制器不存在,則將其傳遞給它的父視圖。

25.7.2.如果視圖或它的控制器無法處理收到的事件或消息,則將其傳遞給該視圖的父視圖。

25.7.3.每一個在視圖繼承樹中的上層視圖如果不能處理收到的事件或消息,則重復(fù)上面的步驟 24.7.1,24.7.2。

25.7.4.在視圖層次結(jié)構(gòu)的最頂級視圖,如果也不能處理收到的事件或消息,則其將事件或消息傳遞給window對象進行處理。

25.7.5.如果window對象也不處理,則其將事件或消息傳遞給UIApplication對象。

25.7.6.如果UIApplication也不能處理該事件或消息,則將其丟棄。

25.8.UIView不接收處理事件的情況:

25.8.1.不接收用戶交互: userInteractionEnabled = NO ;

25.8.2.隱藏: hidden = YES ;

25.8.3.透明: alpha = 0~0.01 。

26.手勢識別

26.1.手勢識別( Gesture Recognizer ),其目的是為了:

26.1.1.簡化開發(fā)者的開發(fā)難度

26.1.2.統(tǒng)一用戶體驗

26.2.iOS 支持的手勢識別:

26.2.1.UITapGestureRecognizer(點按)

26.2.2.UIPinchGestureRecognizer(捏合)

26.2.3.UIPanGestureRecognizer(拖動)

26.2.4.UISwipeGestureRecognizer(輕掃)

26.2.5.UIRotationGestureRecognizer(旋轉(zhuǎn))

26.2.6.UILongPressGestureRecognizer(長按)

26.3.手勢識別的狀態(tài):

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

|

typedef NS_ENUM``(``NSInteger``, UIGestureRecognizerState) {

// 沒有觸摸事件發(fā)生,所有手勢識別的默認狀態(tài)

UIGestureRecognizerStatePossible,

// 一個手勢已經(jīng)開始但尚未改變或者完成時

UIGestureRecognizerStateBegan,

// 手勢狀態(tài)改變

UIGestureRecognizerStateChanged,

// 手勢完成

UIGestureRecognizerStateEnded,

// 手勢取消,恢復(fù)至Possible狀態(tài)

UIGestureRecognizerStateCancelled,

// 手勢失敗,恢復(fù)至Possible狀態(tài)

UIGestureRecognizerStateFailed,

// 識別到手勢識別

UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded

};

|

也被稱為離散手勢,該手勢識別不會被取消,只是調(diào)用一次 selector 任務(wù)。

26.4.屬性:

| state | 手勢狀態(tài) |
| view | 手勢發(fā)生視圖 |

26.5.常用方法:

| locationInView | 獲得手勢發(fā)生對應(yīng)視圖所在位置 |
| translationInView | 相對于起始位置在視圖中的平移位置 |

26.6.手勢使用的步驟:

26.6.1.實例化手勢

26.6.2. 指定手勢參數(shù)

26.6.3. 將手勢附加到指定視圖

26.6.4. 編寫手勢監(jiān)聽方法

26.7.imageView默認是不支持用戶交互的,需要:

|

1

|

[imageView setUserInteractionEnabled:``YES``];

|

26.8.UITapGestureRecognizer (點按)

|

1

2

3

4

5

6

7

|

//點按手勢 Tap

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:``self action:``@selector``(tap:)];

// 點按次數(shù)

[tap setNumberOfTapsRequired:2]; //雙擊

// 用幾根手指點按

[tap setNumberOfTouchesRequired:1];

[imageView addGestureRecognizer:tap];

|

26.9.UIPinchGestureRecognizer (捏合)

|

1

2

3

|

//縮放(捏合)手勢 Pinch

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:``self action:``@selector``(pinch:)];

[imageView addGestureRecognizer:pinch];

|

26.10.UIPanGestureRecognizer(拖動)

|

1

2

3

|

//拖動手勢 Pan

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:``self action:``@selector``(pan:)];

[imageView addGestureRecognizer:pan];

|

26.11.UISwipeGestureRecognizer (輕掃)

26.11.1.手指在屏幕上掃動,和拖動手勢的區(qū)別在于,手指離開屏幕才會觸發(fā)監(jiān)聽方法。

26.11.2.手指可以上、下、左、右四個方向輕輕掃動,如果沒有指定方向,默認都是向右掃動。

26.11.3.在設(shè)置輕掃手勢時,通常需要將手勢識別添加到父視圖上監(jiān)聽。

26.11.4.在監(jiān)聽方法中,注意不要使用recognizaer.view,因為手勢監(jiān)聽的是父視圖,而要處理的視圖通常是其他的視圖。

26.11.5.如果要使用多個方向的輕掃手勢,需要指定多個輕掃手勢。

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

|

//輕掃手勢 Swipe

//上

UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc]initWithTarget:``self action:``@selector``(swipe:)];

[swipeUp setDirection:UISwipeGestureRecognizerDirectionUp];

[``self``.view addGestureRecognizer:swipeUp];

//下

UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc]initWithTarget:``self action:``@selector``(swipe:)];

[swipeDown setDirection:UISwipeGestureRecognizerDirectionDown];

[``self``.view addGestureRecognizer:swipeDown];

//左

UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:``self action:``@selector``(swipe:)];

[swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];

[``self``.view addGestureRecognizer:swipeLeft];

//右

UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:``self action:``@selector``(swipe:)];

[swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];

[``self``.view addGestureRecognizer:swipeRight];

- (``void``)swipe:(UISwipeGestureRecognizer *)recognizer

{

// ...

if (UISwipeGestureRecognizerDirectionUp == recognizer.direction) {

//上

// ...

} else if (UISwipeGestureRecognizerDirectionDown == recognizer.direction) {

//下

// ...

} else if (UISwipeGestureRecognizerDirectionLeft == recognizer.direction) {

//左

// ...

} else {

//右

// ...

}

// ...

}

|

26.12.UIRotationGestureRecognizer (旋轉(zhuǎn))

|

1

2

3

|

//旋轉(zhuǎn)手勢 Rotation

UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:``self action:``@selector``(rotation:)];

[imageView addGestureRecognizer:rotation];

|

26.13.UILongPressGestureRecognizer (長按)

|

1

2

3

|

//長按手勢 Long Press

UILongPressGestureRecognizer *longTap = [[UILongPressGestureRecognizer alloc]initWithTarget:``self action:``@selector``(longTap:)];

[imageView addGestureRecognizer:longTap];

|

27.搖晃監(jiān)聽

27.1.使用方法:

27.1.1.新建搖晃監(jiān)聽自定義視圖 ,如:ShakeListenerView,并且設(shè)置 canBecomeFirstResponder 返回 YES。

27.1.2.將 ViewController 的根視圖設(shè)置為自定義視圖,如:ShakeListenerView。

27.1.3.在 ViewController.m 文件中增加:viewDidAppear 和 viewDidDisappear 在視圖出現(xiàn)和消失時成為/撤銷第一響應(yīng)者身份。

27.1.4.在視圖控制器中增加運動事件監(jiān)聽方法。

27.2.因為 UIResponder 的 canBecomeFirstResponder 屬性,默認為 NO,而在監(jiān)聽搖晃事件時,需要把根視圖變成第一響應(yīng)者,因此常常需要自定義一個搖晃監(jiān)聽視圖 ,如:ShakeListenerView。

<caption style="border: 0px !important; margin: 0px !important; padding: 0.5em 0px 0.5em 1em !important; vertical-align: baseline !important; border-radius: 0px !important; background: none !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline: 0px !important; overflow: visible !important; position: static !important; right: auto !important; text-align: left !important; top: auto !important; width: auto !important; box-sizing: content-box !important; font-family: Monaco, Consolas, "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; direction: ltr !important; box-shadow: none !important; color: black !important;">ShakeListenerView.m</caption>
|

1

2

3

4

|

- (``BOOL``)canBecomeFirstResponder

{

return YES``;

}

|

<caption style="border: 0px !important; margin: 0px !important; padding: 0.5em 0px 0.5em 1em !important; vertical-align: baseline !important; border-radius: 0px !important; background: none !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; outline: 0px !important; overflow: visible !important; position: static !important; right: auto !important; text-align: left !important; top: auto !important; width: auto !important; box-sizing: content-box !important; font-family: Monaco, Consolas, "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 1em !important; direction: ltr !important; box-shadow: none !important; color: black !important;">ViewController.m</caption>
|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

|

- (``void``)viewDidAppear:(``BOOL``)animated

{

[``self``.view becomeFirstResponder];

}

- (``void``)viewDidDisappear:(``BOOL``)animated

{

[``self``.view resignFirstResponder];

}

- (``void``)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event

{

if (UIEventSubtypeMotionShake == motion) {

// 搖晃了

// ...

}

}

|

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容