UITableView
用來管理一組數據,繼承自UIScrollView,可以滾動;可以分區(分組)顯示內容,tabView中分區稱爲section,每一行稱爲row;frame屬性決定tableView的顯示位置,邊框;而row表示tableView中的某一行的位置,row的數量決定contentSize的大小,tableView根據行數及行高自動計算它;每一行的位置都會放置一個UITableViewCell,負責顯示本行的內容;有兩種數據綁定方式,靜態和動態綁定,其中靜態單元格必須使用UITableViewController控制器;而動態綁定則沒有限制約束;
1.常用屬性
tableView.rowHeight = 60; // 統一設置行高,通常當每一行的內容樣式相同並且高度固定時(高效);
tableview.sectionHeaderHeight = 44; // 設置每組的組標題的高度;
tableview.separatorColor // 分割線顏色
tableview.separatorStyle // 分割線樣式
tableview.tableHeaderView // headerView
tableview.tableFooterView // 只能修改x和height的值,y和width不能修改;
tableView.tableFooterView.hidden = NO; // 控制是否顯示FooterView
tableview.allowsSelection // 是否允許選中某一行;
tableView.sectionFooterHeight = 0; // 組尾高度
tableView.sectionHeaderHeight = 10; // 組頭高度
tableView.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0);
// 默認情況下UITableViewController中的tableView的第一行會有一段比較高的距離,可通過更改contentInset來改變此距離;
2、數據刷新
reloadData;
reloadInputViews;
reloadSectionIndexTitles;
reloadSections:(NSIndexSet *) withRowAnimation:(UITableViewRowAnimation);
[tableView reloadData];
// 重新刷新tableView,重新調用UITableView的數據源對象中的方法;
[tableView reloadRowsAtIndexPaths:
(NSArray *) withRowAnimation:(UITableViewRowAnimation)];
// 局部刷新,刷新指定的行,第一個參數array爲需要刷新的行的數組,數組元素對象爲NSIndexPath實例;
3.其它方法
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:(UITableViewScrollPosition) animated:YES]; // 滾動到某一行
[tableView indexPathForSelectedRow]; // 獲取當前選中的項
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:index];
[tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationLeft]; // 刷新某組
4.樣式設置
UITableViewController默認的tableView是plain樣式,如果需要改成Grouped樣式,則可以重寫控制器的init方法
-(id)init {
return [self initWithStyle:UITableViewStyleGrouped];
}
tableView的backgroundView優先級要比backgroundColor要高,如果想要改變背景,則通常修改backgroundView=nil,再設置背景顏色;
其它:
<1>.設置section爲多個section,再把UITableView樣式改變Plain,則滾動的時候會把當前所滾動到的group的title顯示到最頂端;
<2>.在iOS6下的UITableViewCell,默認contentView的frame的x爲10,如果想要和iOS7一樣,需要重寫setFrame方法,讓frame.size.width加10,frame.origin.x減10;
UITableViewDelegate
// 如果每行行高不一樣,則需要通過代理的方式設置;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
// section組頭的height
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
// section組尾的height
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
// cell縮進級別
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath;
// section組頭的view
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
// section組尾的view
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
注:不要在代理的獲取組頭/組尾View方法中直接返回一個UIView對象,因爲這樣無法實現重用該UIView,爲了能重用每個Header中的UIView,這裏需要返回一個UITableViewHeaderFooterView;
UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section // 每個section的row數量
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath //設置每個row上的cell
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
// section組頭的title
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
// section組尾的title
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
// section索引的title集合
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView;
UITableView數據源的添加,刪除,移動,都需要對相應的數據源進行處理;
通常使用UITableViewController來替換UIViewController+UITableView的組合,前者是UIViewController的子類,內部封裝了UITableView,實現了基本的代理方法;常用的一個屬性是clearsSelectionOnViewWillAppear,默認值爲NO;
UITableViewCell
列表數據顯示基本單元格,顯示每一行row的內容,系統默認提供四個樣式:
UITableViewCellStyleDefault、Subtitle、Value1、Value2;
- 編輯:editView、TableView被編輯時顯示;
- 內容:contentView,包含imageView,textLabel,detailTextLabel
- 輔助:accessoryView,顯示cell的輔助信息;
1.初始化
initWithStyle // 只有在通過代碼創建控制的時候纔會調用,如果控件是通過xib或者storyboard創建的,則不會調用該方法;
awakeFromNib // 如果控件是通過xib或者storyboard創建出來的,則調用此方法,此方法只會調用一次;
layoutSubviews: // 當控件的frame被修改的時候就會被調用,一般在此方法中佈局子控件;
注意:UITableViewCell在UITableView的代理方法cellAtIndex…方法中,不能設置它的cell元素的frame等屬性,因爲在return cell後,cell的layoutSubviews會自動覆蓋之前設置的frame屬性;
2.常用屬性
imageView
textLabel
detailTextLabel
accessoryType // 輔助效果(系統提供默認三種樣式,UITableViewCellAccessoryCheckmary,Disc...)
accessoryView
backgroundView
selectedBackgroundView
backgroundColor
selectionStyle // 選中效果
indentationLevel 縮進
3.Cell交互控制
// 輔助button被點擊
-(void) tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
// cell將要取消選中
- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath
// cell將要被選中
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
// cell被選中
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
// cell被取消選中
- (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
// 取消選中某行
- (void) deselectRowAtIndexPath: animated:
優化:獲取cell的方法中,把緩存tag設置爲static,不會頻繁創建該tag;通常單元格里面的view不是直接添加到UITableViewCell裏面的,而是添加到UITableViewCell的contentView裏面的;
4.自定義cell
<1>.新建一個類繼承自UITableViewCell
<2>.在initWithStyle方法中對子控件進行初始化
- 將有可能顯示的所有子控件都添加到contentView中
- 設置一些固定不變的屬性
<3>.提供兩個模型
- 數據模型
- frame模型(數據模型+所有子控件的frame+cell高度)
<4>.cell需要提供一個frame模型屬性
- 將frame模型傳遞給cell
- cell根據frame模型給子控件設置frame,根據數據模型給子控件設置數據
- cell根據數據模型決定顯示和隱藏哪些子控件
<5>.在tableView的代理方法中返回cell的高度
cell.backgroundView; // 指定cell的背景view
cell.selectedBackgroundView; // 指定cell的選中背景view
NSIndexPath
1.索引路徑,用於標識row
+(NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section;
2.屬性
section
row
在剛剛創建好的headerView中獲取的header的frame是0,當程序運行時,headerView就有frame了,因爲在此方法中,將headerView返回後,UITableView在執行的時候,會用到headerView,UITableView既然要用headerView,則需要將headerView添加到UITableView中,當把headerView添加到UITableView的時候,UITableView內部會根據一些設置來動態的爲headerView設置frame值,也就是說在UITableView即將用到headerView時,纔會給它設置frame值;
3.UITableView的編輯
1.tableView進入編輯狀態
2.詢問tableView的cell是否能夠編輯
3.詢問tableView的cell的編輯類型
4.tableView響應編輯操作
UITabelViewCell的移動
1.tableView進入編輯狀態
2.訪問tableView能否移動
3.確認tableView移動位置
4.tableView響應移動操作
其它:
添加下拉刷新控件
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[tableView addSubView:refreshControl];
[refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
UICollectionView
用法基本和UITableView一樣,也有數據源和代理;
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView // 返回section數量;
// 返回第section組有多少個item;
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
// 返回indexPath對應的section組的item項顯示內容;
-(UICollectionViewCell *)collectionView: cellForItemAtIndexPath:(NSIndexPath *)indexPath
Scroll 函數
// 滾動到指定位置
[collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:50] atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
// 獲取當前可見的條目
NSIndexPath *path = [[collectionView indexPathsForVisibleItems] lastObject];
// scrollView停止滾動
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
與UITableView的差別是:
1.通過dequeueXxx方法獲取一個cell,如果緩存的cell爲空,系統自動會爲我們創建好cell並且返回回來,所以不用我們手動alloc init;
2.在獲取cell之前,必須先註冊一個cell到系統中(如果緩存池中沒有identifier對應的cell,則會自動創建註冊的class對應的cell);
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"]; // 通常把放到viewDidLoad方法中;
3.如果cell不是通過alloc init方法創建的,而是通過xib來創建的,則需要註冊一個xib;
UINib *nib = [UINib nibWithNibName:@"cellItem" bundle:nil];
// 需要注意的是,要把cellItem.xib中的identifier設置爲cell,和代碼中相同;
[collectionView registerNib:nib forCellWithResuseIdentifier:@"cell"];
4.UICollectionView must be initialized with a non-nil layout parameter;
創建UICollectionView的時候,必須傳入一個非空的layout參數;在自定義的UICollectionViewController中,重寫init方法;
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; // 創建一個UICollectionViewLayout,該佈局對象決定將來CollectionView上每個item的顯示方式;
layout.itemSize = CGSizeMake(100, 100); // 設置每一個item的寬高;
layout.minmumLineSpacint = 20; // 設置item行間距;minimumInteritemSpacint(列間距);
layout.headerReferenceSize = CGSizeMake(0, 100); // 設置CollectionView距離上邊的高度,(footerReferenceSize);
layout.sectionInset = UIEdgeInsetsMake(10, 20, 30, 40); // 設置CollectionView的padding(上左下右);
self = [super initWithCollectionViewLayout:layout]; // 初始化的時候傳入創建的佈局對象;
UIWebView
-(void)loadRequest:(NSURLRequest *)request;
-(void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL;
// 加載本地文件
NSURL *url = [[NSURL alloc] initFileURLWithPath:path]; // 根據路徑獲取URL;
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; // 創建Request;
[webView loadRequest:request];
html跳轉
window.location.href = "http://www.baidu.com";
window.loaction.href = "#elementId";
// 讓webview執行javascript代碼,跳轉到指定位置;
[webview stringByEvaluatingJavaScriptFromString:@"window.location.href = '#xxId'"];
// document.getElementsByTagName('header')[0].remove(); 從Document中移除自己;
webview.scalesPageToFit = YES; // 伸縮內容至適應屏幕;
[webview loadRequest:[NSURLRequest requestWithURL:"http://www.baidu.com"]];
// 如果webview在顯示的時候沒顯示完全,可檢查ViewController的Adjust Scroll View Insets屬性;
-(void)reload;
-(void)stopLoading;
-(void)goBack|goForward;
@property(nonatomic) UIDataDetectorTypes dataDetectorTypes; // 需要進行檢測的數據類型;
@property(nonatomic, getter=isLoading) BOOL loading; // 是否正在加載中;
@property(nonatomic) BOOL scalesPageToFit; // 伸縮內容到適應屏幕尺寸;
代理方法
-(BOOL)webView: shouldStartLoadWithRequest:request navigationType:navigationType
{
NSString *url = request.URL.absoluteString;
NSRange range = [url rangeOfString:@"ios://"];
if (range.length !=0){
NSString *method = [url substringFormIndex:range.location + range.length];
SEL selector = NSSelectorFormString(method); // 將方法轉爲SEL類型;
[self performSelector:selctor withObject:nil];
}
} // webview發送一個請求之前都會調用這個方法