iOS UITableView、UICollectionView、UIWebView

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方法中對子控件進行初始化

  1. 將有可能顯示的所有子控件都添加到contentView中
  2. 設置一些固定不變的屬性

<3>.提供兩個模型

  1. 數據模型
  2. frame模型(數據模型+所有子控件的frame+cell高度)

<4>.cell需要提供一個frame模型屬性

  1. 將frame模型傳遞給cell
  2. cell根據frame模型給子控件設置frame,根據數據模型給子控件設置數據
  3. 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發送一個請求之前都會調用這個方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章