1.UIView
1.1.所有 UI 控件都繼承自 UIView。
1.2.每一個 UIView 都是一個容器,可以容納其他 UIView。其中容器視圖被稱為父視圖,而被包含的視圖或者控件被成為子視圖或者子控件。
1.3.視圖對應的文件通常是 storyboard 或者 xib 文件。在許多 iOS 應用程序中,通常不必為視圖編寫任何代碼。
1.4.UIView 負責界面的顯示。
1.5.常用屬性:
superview | 獲得自己的父控件對象 |
subviews | 獲得自己的所有子控件對象 |
一個視圖最多只能有一個父視圖,一個視圖可以有多個子視圖。
frame | 控件所在矩形框的位置和尺寸(以父控件的左上角為坐標原點) |
bounds | 控件所在矩形框的位置和尺寸(以自己左上角為坐標原點,所以bounds的x和y永遠為0) |
center | 控件中點的位置(以父控件的左上角為坐標原點),通過center屬性設置視圖位置更加方便 |
用 frame 和 center 可以修改 UIView 的位置。
用 frame 和 bounds 可以修改 UIView 的尺寸。
通常,修改自身位置大小時使用 frame,而子視圖(控件)在設置位置時,會相對父視圖的 bounds 進行設置。
tag | 控件的ID(標記),父控件可以通過tag來找到或區分子控件 |
tag 為一個整數,並且兩個控件的 tag 默認為0,也可能相同。而在使用 tag 來找到或區分子控件時只會返回第一個與之相符的子控件。
transform | 控件的形變屬性(可以設置旋轉角度、比例縮放、平移等屬性) |
UIView 一次只能應用一個形變屬性
設置 transfrom 會改變 UIView 的 frame 屬性,但不會改變 bounds 屬性。
CGAffineTransformMakeRotate、CGAffineTransformMakeScale、CGAffineTransformMakeTranslation 相對 UIView 的初始狀態進行形變
CGAffineTransformRotate、CGAffineTransformScale、CGAffineTransformTranslation 相對 UIView 的當前狀態進行形變
1.6.動畫
1.6.1.UIView 封裝的簡單動畫效果
1
2
3
4
5
6
|
[UIView beginAnimations:
nil
context:
nil
];
// 設置動畫持續時間
[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 動畫的優勢:
可以在動畫完成時做一些其他的任務
可以設置動畫延遲及動畫效果選項
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 | 按鈕的內容需要自定義 |
UIButtonTypeRoundedRect | 圓角矩形按鈕 |
UIButtonTypeDetailDisclosure | 顯示明細按鈕 |
UIButtonTypeInfoLight | 亮色信息按鈕,用於深色背景 |
UIButtonTypeInfoDark | 深色信息按鈕,用戶淺色背景 |
UIButtonTypeContactAdd | 添加按鈕 |
2.2.基本設置
2.2.1.設置文字
在設置按鈕文字時,需要指定文字對應的按鈕狀態:
1
2
3
4
|
//正常狀態下按鈕文字
[btn setTitle:
@"正常"
forState:UIControlStateNormal];
//長按按鈕狀態下的按鈕文字
[btn setTitle:
@"長按"
forState:UIControlStateHighlighted];
|
2.2.2.設置文字顏色
在設置按鈕文字顏色時,也需要指定文字對應的按鈕狀態:
1
2
|
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
|
2.2.3.設置背景顏色
1
|
[btn setBackgroundColor:[UIColor orangeColor]];
|
2.2.4.設置圖片及背景圖像
1
2
3
4
5
6
|
// 加載圖像
UIImage *image = [UIImage imageNamed:
@"sub_black_add.png"
];
// 設置按鈕圖像
[btn setImage:image forState:UIControlStateNormal];
// 設置按鈕背景圖像
[btn setBackgroundImage:image forState:UIControlStateNormal];
|
背景圖像會根據按鈕的尺寸拉伸,按鈕圖像會居中顯示在按鈕中央位置。
如果同時設置了按鈕的圖像和文字,按鈕區域足夠大,會並列顯示圖像和文字,如果區域不夠大,優先顯示圖像。
2.3.設置按鈕點擊監聽
1
2
|
// 設置按鈕點擊監聽
[btn addTarget:
self
action:
@selector
(tapButton) forControlEvents:UIControlEventTouchUpInside];
|
調用自定義方法需要使用 @selector 指令,按鈕事件最多只可以帶一個參數。
3.UILabel
3.1.實例化:
1
2
|
// 實例化 UILabel 並指定其邊框
UILabel *label = [[UILabel alloc]initWithFrame:rect];
|
3.2.基本設置
3.2.1.設置文本
1
|
[label setText:
@"Hello World"
];
|
3.2.2.設置字體和字體大小
1
|
[label setFont:[UIFont fontWithName:
@"Helvetica-Bold"
size:40]];
|
3.2.3.設置背景色
1
|
[label setBackgroundColor:[UIColor greenColor]];
|
3.2.4.設置文本的顏色
1
|
[label setTextColor:[UIColor whiteColor]];
|
3.2.5.設置文本的陰影色彩和透明度
1
|
[label setShadowColor:[UIColor colorWithWhite:0.1f alpha:0.8f]];
|
3.2.6.設置陰影的偏移量
1
|
[label setShadowOffset:CGSizeMake(2.0f, 2.0f)];
|
3.2.7.設置文本的對齊方式
1
|
[label setTextAlignment:
NSTextAlignmentCenter
];
|
3.2.8.指定換行模式
1
|
[label setLineBreakMode:
NSLineBreakByWordWrapping
];
//按照單詞換行的方式處理
|
3.2.9.指定行數,為0時沒有最大行數限制
1
|
[label setNumberOfLines:2];
|
4.UITextField
4.1.作用:供用戶輸入或編輯文本
4.2.text 屬性:獲得或設置文本框中的文字
4.3.使用文本框控件時的注意事項:
4.3.1.在輸入不同類型的文本時,需要注意鍵盤的類型。
4.3.2. 如果界面上有多個文本框供用戶輸入時,要注意回車鍵的設置,實現文本框由上至下的切換,切換到最后一個文本框,再按回車鍵時,調用對應的確認按鈕的方法。
4.3.3.需要注意關閉鍵盤,關閉鍵盤有兩種方法:
1
2
3
4
|
//1
[
self
.view endEditing:
YES
];
//2
[textField resignFirstResponder];
|
4.3.4.要監聽文本框的回車事件,需要設置文本框的delegate,同時讓視圖控制器遵從<UITextFieldDelegate>協議。
4.4.設置鍵盤和鍵盤上面的工具欄
1
2
3
4
|
// 設置日期文本的輸入鍵盤
[_dateText setInputView:datePickerView];
// 設置鍵盤上面的工具控件
[_dateText setInputAccessoryView:toolView];
|
4.5.常用代理方法:
1
2
3
4
5
6
7
8
9
10
11
|
// 當文本框開始獲得焦點的時候調用
- (
void
)textFieldDidBeginEditing:
// 當用戶失去焦點的時候調用
- (
void
)textFieldDidEndEditing:
// 在文本框准備聚焦的時候調用,返回NO代表不允許聚焦(編輯)
- (
BOOL
)textFieldShouldBeginEditing:
// 在文本框准備失去焦點(退出鍵盤)的時候調用,返回YES代表允許退出鍵盤
- (
BOOL
)textFieldShouldEndEditing:
// 在用戶每次輸入的時候都會調用,返回YES代表允許輸入
- (
BOOL
)textField:
shouldChangeCharactersInRange:replacementString:
|
5.UIImageView (圖像視圖)
5.1.作用:
專門用來顯示圖片的控件
5.2.基本設置
5.2.1.設置圖像
1
|
[
self
.imageView setImage:[UIImage imageNamed:
@"abc.png"
]];
|
5.2.2.設置顯示模式
1
2
|
//設置圖片居中顯示,並且保持原來寬高比
imageView.contentMode = UIViewContentModeScaleAspectFit;
|
5.3.UIImageView的序列幀動畫
5.3.1.UIImageView可以讓一系列的圖片在特定的時間內按順序顯示。
5.3.2.屬性說明:
animationImages | 要顯示的一組圖片序列 |
animationDuration | 完整地顯示所有圖片所需的時間 |
animationRepeatCount | 動畫的執行次數(默認為0,代表無限循環) |
5.3.3.相關方法:
- (void)startAnimating; | 開始動畫 |
- (void)stopAnimating; | 停止動畫 |
- (BOOL)isAnimating; | 是否正在運行動畫 |
6.UISlider (滑塊控件)
6.1.作用:
用來顯示進度值,並且可以手動修改進度值
6.2.基本設置
1
2
3
4
5
6
|
// 設置滑塊最大值
[slider setMaximumValue:15];
// 設置滑塊最小值
[slider setMinimumValue:0];
// 設置滑塊當前數值
[slider setValue:5];
|
6.3.事件監聽
1
2
3
4
5
6
7
|
//監聽 UISlider 的進度值改變,要使用 Value Changed 事件
//通過代碼為 UISlider 添加監聽器:
[slider addTarget:
self
action:
@selector
(sliderChange:) forControlEvents:UIControlEventValueChanged];
//當UISlider 的進度值發生改變時,會自動調用 self 的 sliderChange:方法,並且將 UISlide r作為第一個參數傳入
- (
void
) sliderChange:(UISlider *)slider
{
}
|
7.UISwitch (開關控件)
7.1.作用:開關
7.2.基本設置
1
2
3
4
|
//設置On或者Off
[mySwitch setOn:
YES
];
//判斷當前狀態
BOOL
state = [mySwitch isOn];
|
7.3.事件監聽
監聽 UISwitch 的狀態改變,要使用 Value Changed 事件(可參照 UISlider 的使用)。
8.UIStepper (計數器控件)
8.1.作用:計數
8.2.基本設置與滑塊控件類似。
8.3.與滑塊控件的區別:
8.3.1.每按一次減號,value 就會自動減去一定的數值(數值大小由 stepValue 決定)。
8.3.2.每按一次加號,value 就會自動增加一定的數值(數值大小由 stepValue 決定)。
8.4.事件監聽
監聽 UISwitch 的狀態改變,要使用 Value Changed 事件(可參照 UISlider 的使用)。
9.UISegmentControl (選項卡控件)
9.1.作用:同一時刻只能選中一個標簽
9.2.基本設置
1
2
|
NSArray
*items = @[
@"1列"
,
@"2列"
,
@"3列"
];
UISegmentedControl *control = [[UISegmentedControl alloc] initWithItems:items];
|
9.3.獲得當前被選中的標簽位置
1
|
int
index = control.selectedSegmentIndex;
|
9.4.事件監聽
監聽 UISwitch 的狀態改變,要使用 Value Changed 事件(可參照 UISlider 的使用)。
10.UIScrollView
10.1.作用:
10.1.1.用於顯示超出應用程序窗口大小的內容
10.1.2.允許用戶通過拖動手勢滾動查看視圖中的內容
10.1.3.允許用戶通過捏合手勢縮放視圖中的內容
10.2.常用屬性:
contentSize | 設置UIScrollView的滾動范圍 |
contentOffset | UIScrollView當前滾動的位置 |
contentInset | 增加滾動視圖四周的增加滾動范圍 |
bounces | 是否有彈簧效果 |
scrollEnabled | 是否能滾動 |
showsHorizontalScrollIndicator | 是否顯示水平方向的滾動條 |
showsVerticalScrollIndicator | 是否顯示垂直方向的滾動條 |
indicatorStyle | 設定滾動條的樣式 |
dragging | 是否正在被拖拽 |
tracking | 按住手指還沒有開始拖動的時候值是YES,否則NO |
decelerating | 是否正在減速 |
zooming | 是否正在縮放 |
10.3.屬性說明
10.3.1.UIScrollView 的完整區域是在 contentSize 的四周增加 contentInset 設定的范圍
10.3.2.UIScrollView 顯示內容的區域由其 frame 屬性決定
10.3.3.UIScrollView 顯示的內容 由 contentOffset 相對 contentSize 的原點決定
10.4.ScrollView的手勢縮放步驟:
10.4.1.設置 UIScrollView 的 id<UISCrollViewDelegate> delegate 代理對象。
10.4.2.設置 minimumZoomScale:縮小的最小比例
10.4.3.設置 maximumZoomScale:放大的最大比例
10.4.4.讓代理對象實現以下方法,返回需要縮放的視圖控件
1
|
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
|
與縮放相關的方法還包括:
1
2
3
4
|
// 正在縮放時調用的方法
- (
void
)scrollViewDidZoom:(UIScrollView *)scrollView
// 縮放完成時調用的方法
- (
void
)scrollViewDidEndZooming:(UIScrollView *)scrollView
|
10.4.5.ScrollView實現分頁效果
要實現分頁效果,將滾動視圖的 pagingEnabled 屬性設置為 YES 即可。設置該屬性后滾動視圖會被分割成多個獨立的頁面,用戶原本的滾動體驗會變成了頁面切換的效果。
11.UIPageControl (分頁控制控件)
11.1.要使用滾動視圖的分頁效果,通常會配合 UIPageControl 分頁控制控件,以增強分頁效果。
UIPageControl的頁數和UIScorllView中的實際頁數是分別處理的,二者之間不必一一對應。
11.2.常用屬性:
numberOfPages | 總頁數 |
currentPage | 當前的頁碼 |
hidesForSinglePage | 當只有一頁的時候,是否要隱藏視圖 |
currentPageIndicatorTintColor | 當前選中頁面標示的顏色 |
pageIndicatorTintColor | 其他頁面標示的顏色 |
11.3.事件監聽(監聽頁面變化)
1
2
3
4
|
// 添加事件監聽方法
[pageControl addTarget:
self
action:
@selector
(pageChanged:) forControlEvents:UIControlEventValueChanged];
// 頁面變化調用方法
- (
void
)pageChanged:(UIPageControl *)pageControl
|
12.UIDatePicker
12.1.作用:方便用戶的日期選擇,並保證日期格式正確
12.2.實例化:
1
2
|
// 實例化日期控件,不用設置寬高,因為它的寬高是固定的
UIDatePicker *datePicker = [[UIDatePicker alloc]init];
|
12.3.基本設置
1
2
3
4
|
// 設置日期控件區域為簡體中文
[datePicker setLocale:[[
NSLocale
alloc]initWithLocaleIdentifier:
@"zh_Hans_CN"
]];
// 設置日期控件格式
[datePicker setDatePickerMode:UIDatePickerModeDate];
|
12.4.事件監聽
1
2
|
// 設定日期控件監聽方法
[datePicker addTarget:
self
action:
@selector
(dateValueChange:) forControlEvents:UIControlEventValueChanged];
|
13.UIPickerView (數據選擇視圖)
13.1.作用:負責從指定的數據源中選擇數據
13.2.要求:使用 PickerView 之前需要指定數據源
13.2.1.數據源負責計算 UIPickerView 有多少列、多少行數據
13.2.2.數據源須遵守 UIPickerViewDataSource 協議,數據源方法如下:
1
2
3
4
|
// 返回總的列數
- (
NSInteger
)numberOfComponentsInPickerView:
// 返回第component列的行數
- (
NSInteger
)pickerView:numberOfRowsInComponent:
|
13.2.3刷新數據方法:
1
|
[pickerView reloadComponent:1];
|
一旦調用了這個方法,就會重新給數據源發送消息計算這列的行數、重新給代理發送消息獲得這列的內容。
13.3.代理
13.3.1.代理可以給 UIPickerView 提供具體的數據、監聽 UIPickerView 的一些事件
13.3.2.代理必須遵守 UIPickerViewDelegate 協議,常用代理方法如下:
1
2
3
4
5
6
7
8
|
// 第component列第row行顯示什么字符串內容
- (
NSString
*)pickerView:titleForRow:forComponent:
// 每當選擇了新的一行就會調用
- (
void
)pickerView:didSelectRow:inComponent:
// 第component列第row行顯示什么樣的UIView,最后一個view參數是用來性能優化的
- (UIView *)pickerView:viewForRow:forComponent:reusingView:
// 返回第component列每一行的高度
- (CGFloat)pickerView:rowHeightForComponent:
|
13.3.3.自定義 PickerView 時,需要指定顯示選擇指示器屬性:
1
|
pickerView.showsSelectionIndicator =
YES
;
|
14.UITableView
14.1.作用:以垂直滾動方式顯示數據列表。
14.2.UITableView 的兩種內置樣式:UITableViewStylePlain 和 UITableViewStyleGrouped 。
14.3.數據源 (dataSource) 和代理 (delegate)
14.3.1.UITableView 需要一個數據源(dataSource)來顯示數據,UITableView 會向數據源查詢一共有多少行數據以及每一行顯示什么數據等。沒有設置數據源的 UITableView 只是個空殼。凡是遵守UITableViewDataSource 協議的 OC 對象,都可以是 UITableView 的數據源。
1
2
3
4
5
6
|
// 一共有多少組數據
- (
NSInteger
)numberOfSectionsInTableView:
// 每一組有多少行數據
- (
NSInteger
)tableView:numberOfRowsInSection:
// 每一行具體顯示的內容
- (UITableViewCell *)tableView:cellForRowAtIndexPath:
|
14.3.2.通常都要為 UITableView 設置代理對象(delegate),以便在 UITableView 觸發一下事件時做出相應的處理,比如選中了某一行。凡是遵守了 UITableViewDelegate 協議的 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的子類,內部有個默認的子視圖:contentView。
14.3.6.contentView是UITableViewCell顯示內容的父視圖,並負責顯示一些輔助指示視圖。
14.3.7.輔助指示視圖的作用是顯示一個表示動作的圖標,可以通過設置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 會用新的數據配置這個 UITableViewCell,然后返回給 UITableView,重新顯示到窗口中,從而避免創建新對象。
14.4.2.UITableViewCell有個NSString *reuseIdentifier屬性,可以在初始化UITableViewCell的時候傳入一個特定的字符串標識來設置reuseIdentifier(一般用UITableViewCell的類名)。當UITableView要求dataSource返回UITableViewCell時,先通過一個字符串標識到對象池中查找對應類型的UITableViewCell對象,如果有,就重用,如果沒有,就傳入這個字符串標識來初始化一個UITableViewCell對象。
14.5.UITableView的編輯模式
14.5.1.UITableView屬有個editing性,當設置為YES時,可以進入編輯模式。在編輯模式下,可以管理表格中的行,比如改變行的排列順序、增加行、刪除行,但不能修改行的內容。
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. 實現UITableViewDataSource的方法:
- (
void
)tableView:commitEditingStyle:forRowAtIndexPath:
//3. 實現UITableViewDelegate的方法:
- (UITableViewCellEditingStyle)tableView: editingStyleForRowAtIndexPath:
//注意:如果不實現該方法,默認將編輯模式視為刪除
|
14.5.4.移動UITableView的行:
1
2
3
4
|
//1. 開啟表格的編輯模式
//2. 實現UITableViewDataSource的方法:
- (
void
)tableView:moveRowAtIndexPath:toIndexPath:
注意:只要實現了該方法,即可實現表格移動
|
14.6.四種刷新表格數據的方法:
1
2
3
4
5
6
7
8
|
// 新增表格數據
[tableView insertRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationTop];
// 刪除表格數據
[tableView deleteRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationRight];
// 局部刷新指定的行
[tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationMiddle];
// 刷新全部表格數據,如果能夠准確確定被修改的數據行,就不要用此方法
[tableView reloadData];
|
14.7.常用屬性
14.7.1.分隔線屬性
separatorStyle | 分隔線樣式 |
separatorColor | 分隔線顏色 |
14.7.2.選中屬性
allowsSelection | 允許選中 |
allowsMultipleSelection | 允許多選 |
14.7.3.行數
indexPathsForSelectedRows | 當前選中行數 |
indexPathsForVisibleRows | 當前可見行數 |
14.7.4.背景
backgroundView | 背景視圖 |
selectedBackgroundView | 選中時的背景視圖 |
14.7.5.UITableViewCell的selectionStyle屬性可設置被選中時的背景顏色:
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.靜態表格
14.9.1.可以等同於 UIViewController 處理。
14.9.2.靜態表格必須嵌入在 UITableViewController 中使用。
14.9.3.可以通過 cellForRowAtIndexPath 方法獲取到用戶當前選中的單元格。
14.9.4.應用場合:針對不需要發生變化的設置或者關於界面的表格視圖布局。
14.9.5.靜態表格無需優化處理。
14.10.提高性能建議:
14.10.1.使用可重用cell:申請內存是需要時間,特別是在一段時間內頻繁的申請內存將會造成很大的開銷,而且上tebleView中cell大部分情況下布局都是一樣的,可以通過回收重用機制來提高性能。
14.10.2.避免content的重新布局:盡量避免在重用cell時候,對cell的內容重新布局,一般情況下,應該在創建cell的時候就將cell布局好。
14.10.3.使用不透明的subView:在定制cell的時,將要添加的subView設置成不透明的會大大減少多個view層疊加時渲染所需要的時間。
15.UISearchBar
15.1.其本身不做任何搜索,而僅是提供一個基本的iOS搜索欄界面
15.2.UISearchBar類用delegate協議的方式來告訴應用程序的其他部分,用戶正在搜索欄中做什么
15.3.程序員需要自己編寫對比字符串和過濾搜索的方法
15.4.實際應用中需要使用Search Bar and Search Display Controller
15.5.常用屬性
Text | 設置出現在搜索欄中的默認字符串,如果需要指定默認搜索內容時使用 |
Placeholder | 在搜索欄沒有添入任何字符串時,一般會顯示一串灰色的字符來提示用戶輸入搜索信息 |
Prompt | 屬性值會出現在搜索欄上方。對於有復雜搜索功能的程序,用戶可能需要一些指導信息 |
Style & Tint | 設置搜索欄的樣式和顏色。建議使用和UINavigationBar上同樣的設置 |
Show Search Results Button | 如果選中此選項,搜索欄右邊會出現一個灰色按鈕。可以用來顯示最近幾次的搜索,或者上次搜索的結果,通過Search Bar的代理方法可以控制該按鈕的行為 |
Show Bookmarks Button | 如果選中此選項,搜索欄右邊會出現一個標准的藍色書簽按鈕。用戶可以調出他們儲存的書簽,通過Search Bar的代理方法可以控制該按鈕的行為 |
Show Cancel Button | 如果選中此選項,搜索欄右邊會出現一個標准的取消按鈕,讓用戶取消搜索。初始不要選中此選項,因為當用戶在搜索欄中輸入內容后,該按鈕會自動出現 |
Shows Scope Bar(顯示范圍欄) & Scope Titles(范圍標題) | 幫助用戶在指定范圍內進行搜索,以縮小搜索范圍 |
Capitalize(大小寫)、Correction(自動糾錯)、Keyboard(鍵盤) | 與UITextField的屬性相同,用於輔助用戶輸入 |
16.UIWebView
16.1.是 iOS 內置的瀏覽器控件,可以瀏覽網頁、打開文檔等,能夠加載 html/htm、pdf、docx、txt等格式的文件,系統自帶的Safari瀏覽器就是通過 UIWebView 實現的。
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];
// 設置數據檢測類型
[_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字符串,不需要顯示整個網頁內容時,通常使用此方法
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.常用導航方法:
goBack | 回退 |
goForward | 前進 |
reload | 重載 |
stopLoading | 取消載入內容 |
16.4.常用屬性:
scalespageToFit | 自動對頁面進行縮放以適應屏幕 |
dataDetectorTypes | 設定電話號碼、網址、電子郵件和日期等文字變為鏈接文字 |
17.UIApplication
17.1.UIApplicationMain
在main.m的main函數中執行了UIApplicationMain這個方法,這是ios程序的入口點:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/*
* argc、argv:ISO C標准main函數的參數,直接傳遞給UIApplicationMain進行相關處理即可
* principalClassName:指定應用程序類,該類必須是UIApplication或其子類。如果為nil,則用UIApplication類作為默認值
* delegateClassName:指定應用程序類的代理類,該類必須遵守UIApplicationDelegate協議
*/
int
UIApplicationMain(
int
argc,
char
*argv[],
NSString
*principalClassName,
NSString
*delegateClassName);
/*
* 方法說明:
* 1) 由第3個參數創建一個UIApplication對象,一個程序對應一個UIApplication對象(單例),UIApplication對象是程序的象征
* 2) 由第4個參數創建一個UIApplication的delegate對象
* 3) 開啟一個消息循環(不斷地監聽地一些系統事件)
* 4) 監聽到相應的事件后,就會給代理發送相應的消息,應用程序啟動完成后,首先會調用代理對象的 application:didFinishLaunchingWithOptions: 方法
*/
UIApplicationMain(argc, argv,
nil
,
NSStringFromClass
([AppDelegate
class
]));
|
17.2. UIApplication 說明
17.2.2.UIApplication 是應用程序的核心,每一個程序在運行期必須有 UIApplication (或子類)的一個實例(有且僅有一個),通過 [UIApplication sharedApplication] 可以得到這個單例實例的指針
17.2.2.UIApplication 幫助管理應用程序的生命周期,而它通過 delegate 來履行這個任務
17.2.4.UIApplication 可以接收事件,把所有用戶事件都放入隊列,逐個處理,它會發送當前事件給一個合適的目標控件進行處理。它還將部分事件轉給 delegate 對象來處理,delegate 可處理的事件包括:應用程序的生命周期事件(如程序啟動和關閉)、系統事件(如來電)。
17.2.5.在開發過程中,UIApplication 是一個非常重要的全局對象。但在實際編程中我們並不直接和UIApplication 對象打交道,而是和其代理打交道,它的代理必須遵守 UIApplicationDelegate 協議,代理提供了相關的生命周期方法來處理應用程序的系統事件
17.2.6.IOS 設備的內存極其有限,如果為 app 分配了太多內存,操作系統會終止 app 的運行,在 UIApplication 接收到這個事件后它會調用代理的 applicationDidReceiveMemoryWarning 方法,代理在這個方法內可以進行釋放內存的操作以防止操作系統強制終止應用程序的運行
17.3.UIApplicationDelegate
17.3.1.ios並不是多任務的操作系統,所以app很容易受到打擾。比如一個來電可能導致app失去焦點,如果這個時候接聽了電話,那么app會自動終止運行
17.3.2.還有很多其它類似的事件會導致 app 失去焦點:
app 失去焦點前會調用代理的applicationWillResignActive ;
app 再次獲取焦點時會調用代理的 applicationDidBecomeActive ;
在運行 app 時鎖屏會調用代理的 applicationWillResignActive;
當屏幕被解鎖時,會調用代理的applicationDidBecomeActive。
17.3.3. 應用程序成為激活狀態后,才可以與用戶進行交互。
17.3.4. 如果要做保存游戲狀態之類操作,應該在注銷激活方法中處理,
因為用戶可能會雙擊home鍵,打開任務欄,此時應用程序不會退出到后台!
17.3.5. 如果要做恢復游戲狀態之類的操作,應該在成為激活方法中處理,
因為用戶可能是從任務欄中返回的。
17.3.6. 如果應用程序運行過程中,內存或其他原因,程序被系統強行退出時,會調用Terminate方法,
開發者,可以再此記錄應用程序被退出前的狀態,以便改進系統
17.3.7. 應用程序退出到后台后,未必會是休眠狀態,有可能會繼續運行,例如:微博、QQ、音樂播放器等軟件
17.3.8. 在UIKit開發中,通常不用在delegate中寫內存警告方法,直接在ViewController中進行處理即可。
17.4.應用程序的完整啟動過程
17.4.1.點擊程序圖標
17.4.2.執行main函數
17.4.3.執行UIApplicationMain函數
17.4.4.創建UIApplication對象、UIApplication的delegate對象
17.4.5.開啟事件循環監聽系統事件
17.4.6.程序加載完畢后調用 delegate 對象的 application:didFinishLaunchingWithOptions: 方法:創建窗口UIWindow對象;創建控制器對象;設置窗口的根控制器;讓窗口成為主窗口、並且可見。
17.5.UIApplication 常用方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 設置圖標右上角顯示的數字
[app setApplicationIconBadgeNumber:10];
// 顯示聯網狀態的提示,一般有網絡請求時,會自動顯示
[app setNetworkActivityIndicatorVisible:
YES
];
// 打開一個URL
// 在iOS中,很多東西都可以通過URL來訪問,例如:電話、短信、電子郵件等
// 比如:
// 打開網站
[app openURL:url];
// 電話會直接呼出
[app openURL:url];
// 會跳出短信發送界面,等待用戶編輯並發送短信
[app openURL:url];
|
18.UIWindow
18.1.UIWindow是一種特殊的UIView,通常在一個app中只會有一個UIWindow,但可以手動創建多個UIWindow
18.2.UIWindow的主要作用:
18.2.1.提供一個區域來顯示視圖
18.2.2.將事件分發給視圖
18.2.3.與UIViewController協同工作,方便完成設備方向旋轉的支持
18.3.將UIView添加到UIWindow中兩種常見方式:
18.3.1.addSubview:直接將 UIView 添加到 UIWindow 中,程序負責維護 UIView 的生命周期以及刷新,但並不會理會 UIView 對應的 UIViewController
18.3.2.setRootViewController:自動將 UIViewController 對應的 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.創建/銷毀自己的 UIView
19.1.2.顯示/隱藏 UIView
19.1.3.處理 UIView 和用戶之間的交互(事件處理)。
19.2.每個 UIViewController 默認都有一個 UIView 屬性。
19.3.UIViewController 負責界面上元素及內容的控制與調度。
19.4.“設置”應用中的界面顯示過程如下:
19.4.1.創建一個 UIViewController
19.4.2.由 UIViewController 創建自己的 UIView(懶加載)
19.4.3.把 UIView 顯示到用戶眼前
19.4.4.UIViewController 監聽並處理 UIView的事件
19.5.loadView 方法
19.5.1.視圖控制器的view懶加載(延遲加載),在使用到view時,才調用控制器的loadView方法加載view
19.5.2.loadView 加載 view 的默認過程(UIViewController的默認實現):
如果nibName有值,就會加載對應的xib文件來創建view,如果nibName沒有值,優先加載同名View.xib文件來創建view,再加載同名ViewController.xib文件來創建view,如果沒有找到上面所述的xib文件,就會用代碼創建一個透明的view。
19.5.3.loadView 方法主要用於處理以代碼的方式實現視圖界面
19.5.4.如果使用storyBoard或者xib方式,不建議重寫loadView方法。
19.5.5.在loadView方法中,不應該調用super loadView方法。
20.UIImagePickerController
20.1.使用 UIImagePickerController 可以選擇照片。
20.2.照片的來源 UIImagePickerControllerSourceType 包括:照片庫、照相機、保存的照片。
20.3.使用步驟:
20.3.1. 判斷照片來源是否可用
20.3.2. 實例化照片選擇控制器
20.3.3. 設置照片源
20.3.4. 設置是否允許編輯
20.3.5. 設置代理
20.3.6. 遵循協議
20.3.7. 顯示照片選擇控制器
20.4.照片選擇代理方法
20.4.1.通過代理方法的 didFinishPickingMediaWithInfo 字典可以獲取選中的照片圖像
20.4.2.關閉照片選擇控制器
20.4.3.保存選中的圖像
21.三種創建應用程序方式小結
21.1.使用代碼方式創建應用程序
21.1.1.在loadView方法中編寫代碼,初始化視圖控件
21.1.2.在viewDidLoad方法中做數據處理
21.2.使用XIB方式創建應用程序
21.2.1.界面設計工作交由XIB文件負責
21.2.2.在viewDidLoad方法中做數據處理
21.2.3.XIB可以設置一組平行關系的視圖/控制器數組,使用靈活,量級較輕
21.3.使用StoryBoard方式創建應用程序
21.3.1.界面設計工作交由StoryBoard負責
21.3.2.在viewDidLoad方法中做數據處理
21.3.3.StoryBoard主要為了方便多視圖控制器之間的切換,量級較重
22.多控制器切換
22.1.視圖控制器常見的切換方式:
22.1.1.Tabbar 選項卡:以 UITabbarController 為容器,以平行的方式是管理子視圖控制器。
22.1.2.Push 推送:以 UINavigationController 為容器,以棧的形式管理子視圖控制器。
22.1.3.Modal 模態:以模態窗口的方式顯示新的視圖控制器,新視圖控制器關閉前,用戶無法與原控制器進行交互。
22.2.容器
22.2.1.容器負責展示一個或者多個 ViewController,並管理這些ViewController的生命周期。
22.2.2.大部分容器本身也是一個 ViewController,被容器管理的這些控制器可以稱為容器的子控制器 ( childViewController ),而容器可以被稱為父控制器 ( parentViewController )。
22.2.3.也有極少數容器不是 ViewController,比如 UIPopoverController,其繼承於 NSObject。(注:UIPopoverController 只能在iPad中使用)
22.2.4.容器可以添加、移除或切換 childViewController。
22.2.5.容器持有所有 childViewController 的實例(一般存在 NSArray 中)。
22.2.6.容器負責 childViewController 的視圖生命周期方法的調用 : viewWillAppear, viewDidAppear, viewWillDisaapper, viewDidDisappear, 旋轉事件等。
22.3.segue 對象的生命周期
22.3.1創建目標視圖控制器。
22.3.2.創建 segue 對象並調用它的 initWithIdentifier:source:destination: 方法,其中的標示符是在 Interface Builder 中指定的唯一標示字符串,另外兩個參數分別對應箭頭的起始控制器和目標控制器。
22.3.3.調用源視圖控制器的 prepareForSegue:sender: 方法。
22.3.4.調用 segue 對象的 perform 方法,負責將目標視圖控制器推送到屏幕。
22.3.5.釋放 segue 對象。
22.4.UITabbarController 和 UINavigationController 結合使用時,要先平行、再層次。
22.5.多視圖控制器跳轉方法:
22.5.1.Model:
打開:presentViewController:animated:completion:
關閉:dismissViewControllerAnimated:completion:
22.5.2.Push:
打開:pushViewController:animated:
關閉: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.2.常用屬性:
childViewControllers | 子視圖控制器 |
title | 標題 |
backBarButtonItem | 返回按鈕 |
leftBarButtonItem | 左側按鈕 |
rightBarButtonItem | 右側按鈕 |
24.3.常用方法:
pushViewController | 將指定視圖控制器壓入棧頂 |
popViewControllerAnimated | 將當前視圖控制器從棧中彈出 |
25.觸摸事件
25.1.UIKit可識別三種類型的輸入事件:觸摸事件、運動(加速計)事件、遠程控制事件。
25.2.UIEvent
25.2.1.iOS 中許多事件對象都是 UIEvent 類的實例,記錄事件產生的時刻和類型。
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.響應者對象
25.3.1.在 iOS 中只有繼承了 UIResponder 的對象才能接收並處理事件。我們稱之為“響應者對象”。
25.3.2.UIApplication、 UIViewController、 UIView 都繼承自 UIResponder,因此它們都是響應者對象,都能夠接收並處理事件。
25.4.觸摸事件的處理
25.4.1.UIView(所有UIKit控件均繼承自 UIView )是 UIResponder 的子類,可以覆蓋下列4個方法處理不同的觸摸事件:
1
2
3
4
5
6
7
8
9
10
11
|
//1. 一根或者多根手指開始觸摸屏幕(在一次觸摸事件中,只會調用一次)
- (
void
)touchesBegan:(
NSSet
*)touches withEvent:(UIEvent *)event
//2.一根或者多根手指在屏幕上移動(隨着手指的移動,會持續調用該方法)
- (
void
)touchesMoved:(
NSSet
*)touches withEvent:(UIEvent *)event
//3.一根或者多根手指離開屏幕(在一次觸摸事件中,只會調用一次)
//如果要調整控件的位置,可以利用 locationInView 和 previousLocationInView 計算移動差值即可
- (
void
)touchesEnded:(
NSSet
*)touches withEvent:(UIEvent *)event
//4.觸摸結束前,某個系統事件(例如電話呼入)會打斷觸摸過程
- (
void
)touchesCancelled:(
NSSet
*)touches withEvent:(UIEvent *)event
//注意:如果希望用戶手指按下屏幕,就立刻做出反應,使用touchesBegan;如果希望用戶手指離開屏幕,才做出反應,使用touchesEnded;通常情況下,應該使用touchesBegan。
|
上述4個方法都有個 UIEvent 的參數,通過 UIEvent 可以得到事件的類型和產生時間,以及當前處於活動狀態的所有觸摸操作。但是,通常會使用 UITouch 對象而不是 UIEvent 對象來處理觸摸事件。
25.4.2.當用戶觸摸屏幕時,系統會創建一個 UITouch 實例,並將該對象和接觸屏幕的那根手指關聯。 UITouch 保存着手指在屏幕上觸摸的位置。當手指移動時,系統會更新同一個 UITouch 對象,使之能夠一直保存該手指在屏幕上的當前位置。當手指離開屏幕時,系統會取消相應的 UITouch 對象。
25.4.3.UITouch對象還會保存一些其他信息,比如,手指的前一個位置、手指按下屏幕的次數(tapCount, 可以用來判斷單擊和雙擊事件)。
25.4.4.因為可以有多根手指同時觸發同一個事件,所以傳給視圖的是一組 UITouch 對象,保存在 NSSet 中,例如:如果兩根手指同時觸摸某個視圖,那么 touchesBegan:withEvent: 的第一個參數是包含兩個 UITouch 實例的 NSSet 對象;如果這兩根手指一前一后分開觸摸同一個視圖,那么視圖會收到兩個獨立的 touchesBegan:withEvent: 消息,並且每個 NSSet 對象中只包含一個 UITouch 對象。因此,根據 NSSet 中UITouch 的個數可以判斷出是單點觸摸還是多點觸摸。
25.4.5.按照響應者鏈順序遞歸查找最先處理事件的UIView,重寫hitTest:withEvent:方法可以攔截觸摸事件。
25.5.UITouch
25.5.1.屬性
window | 觸摸產生時所處的窗口。由於窗口可能發生變化,當前所在的窗口不一定是最開始的窗口 |
view | 觸摸產生時所處的視圖。由於視圖可能發生變化,當前視圖也不一定時最初的視圖 |
tapCount | 點按操作和鼠標的單擊操作類似,tapCount表示短時間內點按屏幕的次數。因此可以根據tapCount判斷單擊、雙擊或更多的點按 |
timestamp | 時間戳記錄了觸摸事件產生或變化時的時間,單位是秒 |
phase | 觸摸事件在屏幕上有一個周期,即觸摸開始、觸摸點移動、觸摸結束,還有中途取消。通過phase可以查看當前觸摸事件在一個周期中所處的狀態。phase是UITouchPhase類型的,是一個枚舉配型,包含: UITouchPhaseBegan(觸摸開始) UITouchPhaseMoved(接觸點移動) UITouchPhaseStationary(接觸點無移動) UITouchPhaseEnded(觸摸結束) UITouchPhaseCancelled(觸摸取消) |
25.5.2.成員函數
- (CGPoint)locationInView:(UIView *)view: | 返回一個CGPoint類型的值,表示觸摸在view這個視圖上的位置,這里返回的位置是針對view的坐標系的。調用時傳入的view參數為空的話,返回的時觸摸點在整個窗口的位置 |
- (CGPoint)previousLocationInView:(UIView *)view: | 該方法記錄了前一個坐標值,函數返回也是一個CGPoint類型的值, 表示觸摸在view這個視圖上的位置,這里返回的位置是針對view的坐標系的。調用時傳入的view參數為空的話,返回的時觸摸點在整個窗口的位置 |
25.6.觸摸事件的傳遞
25.6.1.發生觸摸事件后,系統會將該事件加入到一個由UIApplication管理的事件隊列中
25.6.2.UIApplication會從事件隊列中取出最前面的事件並將其分發以便處理,通常,先發送事件給應用程序的主窗口
25.6.3.主窗口會調用hitTest:withEvent:方法在視圖繼承樹中找到一個最合適的子視圖來處理觸摸事件,該子視圖即為hit-test視圖,如果hit-test視圖不處理收到的事件消息,UIKit則將事件轉發到響應者鏈中的下一個響應者,看其是否能對該消息進行處理
25.7.響應者鏈
響應者鏈條,是通過遞歸構成的一組UIResponder對象的鏈式序列。響應者鏈事件處理過程為:
25.7.1.如果hit-test視圖的控制器存在,就傳遞給控制器;如果控制器不存在,則將其傳遞給它的父視圖。
25.7.2.如果視圖或它的控制器無法處理收到的事件或消息,則將其傳遞給該視圖的父視圖。
25.7.3.每一個在視圖繼承樹中的上層視圖如果不能處理收到的事件或消息,則重復上面的步驟 24.7.1,24.7.2。
25.7.4.在視圖層次結構的最頂級視圖,如果也不能處理收到的事件或消息,則其將事件或消息傳遞給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.簡化開發者的開發難度
26.1.2.統一用戶體驗
26.2.iOS 支持的手勢識別:
26.2.1.UITapGestureRecognizer(點按)
26.2.2.UIPinchGestureRecognizer(捏合)
26.2.3.UIPanGestureRecognizer(拖動)
26.2.4.UISwipeGestureRecognizer(輕掃)
26.2.5.UIRotationGestureRecognizer(旋轉)
26.2.6.UILongPressGestureRecognizer(長按)
26.3.手勢識別的狀態:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
typedef
NS_ENUM
(
NSInteger
, UIGestureRecognizerState) {
// 沒有觸摸事件發生,所有手勢識別的默認狀態
UIGestureRecognizerStatePossible,
// 一個手勢已經開始但尚未改變或者完成時
UIGestureRecognizerStateBegan,
// 手勢狀態改變
UIGestureRecognizerStateChanged,
// 手勢完成
UIGestureRecognizerStateEnded,
// 手勢取消,恢復至Possible狀態
UIGestureRecognizerStateCancelled,
// 手勢失敗,恢復至Possible狀態
UIGestureRecognizerStateFailed,
// 識別到手勢識別
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
};
|
也被稱為離散手勢,該手勢識別不會被取消,只是調用一次 selector 任務。
26.4.屬性:
state | 手勢狀態 |
view | 手勢發生視圖 |
26.5.常用方法:
locationInView | 獲得手勢發生對應視圖所在位置 |
translationInView | 相對於起始位置在視圖中的平移位置 |
26.6.手勢使用的步驟:
26.6.1.實例化手勢
26.6.2. 指定手勢參數
26.6.3. 將手勢附加到指定視圖
26.6.4. 編寫手勢監聽方法
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:)];
// 點按次數
[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.手指在屏幕上掃動,和拖動手勢的區別在於,手指離開屏幕才會觸發監聽方法。
26.11.2.手指可以上、下、左、右四個方向輕輕掃動,如果沒有指定方向,默認都是向右掃動。
26.11.3.在設置輕掃手勢時,通常需要將手勢識別添加到父視圖上監聽。
26.11.4.在監聽方法中,注意不要使用recognizaer.view,因為手勢監聽的是父視圖,而要處理的視圖通常是其他的視圖。
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 (旋轉)
1
2
3
|
//旋轉手勢 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.搖晃監聽
27.1.使用方法:
27.1.1.新建搖晃監聽自定義視圖 ,如:ShakeListenerView,並且設置 canBecomeFirstResponder 返回 YES。
27.1.2.將 ViewController 的根視圖設置為自定義視圖,如:ShakeListenerView。
27.1.3.在 ViewController.m 文件中增加:viewDidAppear 和 viewDidDisappear 在視圖出現和消失時成為/撤銷第一響應者身份。
27.1.4.在視圖控制器中增加運動事件監聽方法。
27.2.因為 UIResponder 的 canBecomeFirstResponder 屬性,默認為 NO,而在監聽搖晃事件時,需要把根視圖變成第一響應者,因此常常需要自定義一個搖晃監聽視圖 ,如:ShakeListenerView。
1
2
3
4
|
- (
BOOL
)canBecomeFirstResponder
{
return
YES
;
}
|
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) {
// 搖晃了
// ...
}
}
轉載
http://docoder.com/移動開發ios-uikit框架/#rd
|