UITableView 所製作出來的應用程式在使用上多半大同小異,它們之間最大的不同還是在表格的呈現方面,如何設計出具有獨特外觀的 UITableView,才是令人頭痛的問題,通常是選擇製作一個全新的 UITableViewCell 來使用,但是你也可以採用比較簡單的做法,使用內建的方法函式來做些微的改變,方式如下。
Table View
整個 Table View 能改變的東西實在不多,多半都是更改背景,但是當你更改背景顏色之後就會發現 Cell 與 Cell 之間會多出一條白線 Separator,你可以參考下列程式碼改變它的顏色或是移除不顯示。
//改變Separator顏色
[self.tableView setSeparatorColor:[UIColor orangeColor]];
//移除Separator
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
Table View Cell
Table View Cell 本身就提供一些不同的類型可供選擇,如下圖,你可以藉由選擇不同的類型來改變文字在 Cell 中編排的方式。
Attributes 中的 Style 屬性 |
另外如果想要在 Cell 中增加其它元件時,可以使用 addSubview 的方法函式來添加新的元件,例如在下列程式碼中,除了設定左右的圖像之外,還自行新增了一個 UILabel 放在其中。
//設定文字背景為透明
[cell.textLabel setBackgroundColor:[UIColor clearColor]];
//設定Cell中左邊的圖片
cell.imageView.image = [UIImage imageNamed:[[heroicaArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row + 1]];
//設定Cell中右邊的連結圖片
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"dice.png"]];
//增加UILabel
UILabel *subtitle = [[UILabel alloc] initWithFrame:CGRectMake(95.0, 45.0, 200.0, 20.0)];
[subtitle setTextColor:[UIColor colorWithHue:1.0 saturation:1.0 brightness:1.0 alpha:0.5]];
[subtitle setBackgroundColor:[UIColor clearColor]];
[subtitle setFont:[UIFont systemFontOfSize:12.0]];
[subtitle setText:@"還可以放注解唷"];
[cell addSubview:subtitle];
//設定背景
[cell setBackgroundView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"CellBG.png"]]];
Section
透過下列內建的方法函式,可以自行更改 Section 的標題內容。
//設定開頭的分類樣式
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *sectionView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 30)];
[sectionView setBackgroundColor:[UIColor brownColor]];
//增加UILabel
UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 18)];
[text setTextColor:[UIColor blackColor]];
[text setBackgroundColor:[UIColor clearColor]];
[text setText:[[heroicaArray objectAtIndex:section] objectAtIndex:0]];
[text setFont:[UIFont boldSystemFontOfSize:16.0]];
[sectionView addSubview:text];
return sectionView;
}
//設定結尾的分類樣式
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
}
Section Index
表格分類的快速索引雖然沒有內建的方法函式可供設定外觀使用,但是你仍然可以透過自製的索引介面並配合下列程式碼,將表格切換到所想要的分類上。
CGRect sectionRect = [self.tableView rectForSection:1];
[self.tableView scrollRectToVisible:sectionRect animated:YES];
備註
如果表格個對應的資料結構有任何問題,可以在「索引式搜索」中的「元件設定」分類裡找到所有有關 UITableView 的文章,查閱其他有關表格的設定方式。
hi 牛奶
回覆刪除請問個問題
我資料庫是用sqlite 我用tableview 顯示出 資料庫內資料及照片網址!並秀出照片在cellimage 現在遇到run 時候會卡卡的~書上寫用NSURLConnection 非同步下載
有人建議用AFNetwork 是否可以給個方向!因為照片url 都在資料庫 所以是不是用NSURLConnection就行~感覺AFNetwork 對我初學者有點難@@以下是我程式碼
我不太曉得加入NSURLConnection 後怎把網址導向 CellImage感謝//設定圖片的url位址
NSURL *url = [NSURL URLWithString:[[custs objectAtIndex:indexPath.row] objectForKey:@"photo1"]];
//使用NSData的方法將影像指定給UIImage
UIImage *urlImage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:url]];
// 從url產生Http request物件
NSURLRequest* request = [NSURLRequest requestWithURL:url];
// 準備建立連線
NSURLConnection* connection =
[[NSURLConnection alloc]
initWithRequest:request delegate:self startImmediately:YES];
// 檢視連線是否順利生成
if (connection) {
// 生成則初始化m_data準備接收
m_data = [NSMutableData data];
} else {
// 沒有辦法生成則產生警告訊息
UIAlertView* alertView =
[[UIAlertView alloc] initWithTitle:@"連線失敗"
message:@"無法建立連線"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[alertView show];
UIImageView* cellAccessoryView = [[UIImageView alloc]initWithImage:urlImage];
// 設定這個View的大小和使用者行為
cellAccessoryView.userInteractionEnabled = YES;
[cellAccessoryView setFrame:CGRectMake(0, 0, 100, 80)];
// 設定這個View為cell的accessoryView
cell.accessoryView = cellAccessoryView;
return cell;
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// m_status.text = @"下載中";
[m_data appendData:data];
}
Bryan Chen 您好
刪除我覺得你原來這樣就很好了,不太需要使用到 NSURLConnection,NSURLConnection 是適用在http 協定下的東西,既然你已經決定使用 SQLite,就是按照您程式碼所寫的這樣做。
你的問題應該是在「秀出照片在cellimage 現在遇到run 時候會卡卡的」,沒錯吧。
解決這個問題,你可以考慮使用較小的縮圖讓傳給你的device,或是採用非同步的方式,像是只顯示(抓取)目前所顯示範圍的縮圖預覽等等來減少傳輸量,
如果採用同步的方式來實作,最好是製作一個loading畫面來做緩衝,讓device取得所有圖片放置在陣列中再一次顯示。
另外,AFNetwork 的層級比起 NSURLConnection要高的許多,如果你只是要做基本的取值動作,不是很建議使用這麼龐大的 framework,還是建議針對你device的動作自己寫一個對應的 class ,比較恰當。
作者已經移除這則留言。
回覆刪除所以我應該針對下載動作 做非同步 方式 另外做一個 class 然後再把下載完資料倒入 tableview Cell Image 內 加上個loading 圖示緩衝 這樣我進到tableview畫面 既使還沒下載完成 我上下拉畫面 就會順暢不會卡 這樣沒錯吧~~另外確認一下 「非同步下載」是寫到另一個class 不要寫在 tableview 裡面 對嗎
回覆刪除感謝您指導
今天早上 看另一方式 // 需要等下载完才顯示圖片 但可以進入畫面
回覆刪除NSString *url2=[[custs objectAtIndex:indexPath.row] objectForKey:@"photo1"];
UIImageFromURL( [NSURL URLWithString:url2], ^( UIImage * image )
{
cell.ImageView.image=image;
NSLog(@"%@",image);
}, ^(void){
NSLog(@"error!");
});
畫面跑起來比以前順多了~
可是有些小圖在更新時會重複出現別的cell圖示 ~等於是我只有指定一張圖網址沒下載前跑出別的網址圖 ~ 我想是不是要加個下載中顯示預設圖 就可以搞定><晚點試試
感覺好像沒什麼太大的改變,「需要等下载完才顯示圖片」這本身就是使用url載入圖片的機制之一喔。
刪除拍謝~牛大在跟您請教一下~關於上次卡卡的問題~我用NSURLConnection執行
回覆刪除程式碼如下跑起來不會卡卡了~可是關於這句NSURL* url = [NSURL URLWithString:[[custs objectAtIndex:0] objectForKey: @"photo1"]];
因為我只有objectAtIndex:0 所以只下載 0 欄位 photo1的網址圖~所以目前模擬器跑出來都是同一張圖~
我因該怎改才能把所有欄位圖下載並分配到cell裡面~之前在tableView裡面可以用 //NSURL *url = [NSURL URLWithString:[[custs objectAtIndex:indexPath.row] objectForKey:@"photo1"]]; 就會抓取所有圖到指定cell 可是現在輸入NSURL* url = [NSURL URLWithString:[[custs objectAtIndex:indexPath.row] objectForKey: @"photo1"]];
是不行的因為不在tableView裡面@@
~~感謝麻煩指導一下
-(void) beginDownload {
// 取得圖檔的URL
NSURL* url = [NSURL URLWithString:[[custs objectAtIndex:0] objectForKey: @"photo1"]];
// 從url產生Http request物件
NSURLRequest* request = [NSURLRequest requestWithURL:url];
// 準備建立連線
NSURLConnection* connection =
[[NSURLConnection alloc]
initWithRequest:request delegate:self startImmediately:YES];
// 檢視連線是否順利生成
if (connection) {
// 生成則初始化m_data準備接收
m_data = [NSMutableData data];
} else {
// 沒有辦法生成則產生警告訊息
UIAlertView* alertView =
[[UIAlertView alloc] initWithTitle:@"連線失敗"
message:@"無法建立連線"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil];
[alertView show];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//顯示影像
cell.mainImage.image = [UIImage imageWithData:m_data];
return cell;
}
您好:
刪除你的邏輯有點怪怪的,你不寫在 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 這個函式裡,又想分別設定每個 cell,會有點麻煩,你可以回去看看這一篇「UITableView 的資料設定方式」一文:
http://furnacedigital.blogspot.tw/2012/01/uitableview.html
在設定表格裡面的每個項目時,系統會根據你表格項目的多寡來決定要執行多少次上述的函式,所以你必須在此函式中分別設定你的 cell。
你可以選擇程式一直行就先抓圖,將影像存放到陣列,在上述式中分別設定這陣列中的片到 cell 中。
另一中方式,是直接在上述函式中呼叫下載影像的function,逐一下載每張圖片,分別設定。
您好~
回覆刪除感謝您的文章,很實用!
不過遇到一點小問題,我有一個NSMutableArray要分兩段
照步驟都沒問題,直到要自訂Section的時候
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
}
開頭時會多出一個Section,可是我只要兩個
像是如下圖:
----
Section1
----
| Row1 |
| Row2 |
----
Section2
----
|Row11|
----
Section3
----
|Row21|
|Row22|
如何才能把Section1拿掉又能自訂Section?
感謝您~
chen-en Wu 您好:
刪除定義 Section的外觀參考本篇實作應該是沒有太大的問題,你的問題應該是出現在最上頭又多出一個 Section tag,解決方法你可以參考「UITableView 的分類顯示 Sections」一文。
http://furnacedigital.blogspot.tw/2012/02/uitableview-sections.html
在文中將 case 0: 的部分,也就是第一個遇到的 Section tag 拿掉即可(此方法只是不設定文字,但是padding依然存在)。
另一個方式就是分兩個table繪製了!
了解!
刪除有試過您說的拿掉case 0: 不過還是會有padding :(
來試試看說的繪製兩個table
感謝您的解答!