之前,我們已經(jīng)創(chuàng)建了一個(gè)簡(jiǎn)單的表視圖App,用來(lái)顯示菜單列表和圖片。
下面,我們繼續(xù)改進(jìn)該App,是其效果更佳。
?
1)實(shí)現(xiàn)不同的行顯示不同的圖片
2) ?定制表視圖單元格
?
?
1.顯示不同的縮略圖:
?
在修改代碼之前,我們先回顧一下在數(shù)據(jù)行上顯示縮略圖的代碼:
?
?
- (
UITableViewCell
*)tableView:(
UITableView
*)tableView cellForRowAtIndexPath:(
NSIndexPath
*)indexPath
{
? ?
static
NSString
*simpleTableIdentifier =
@"simpleTableItem"
;
? ?
UITableViewCell
*cell = [tableView
dequeueReusableCellWithIdentifier
:simpleTableIdentifier];
?
? ?
if
(cell ==
nil
) {
? ? ? ? cell = [[
UITableViewCell
alloc
]
initWithStyle
:
UITableViewCellStyleDefault
reuseIdentifier
:simpleTableIdentifier];
? ? }
?
cell.
textLabel
.
text
= [
tableData
objectAtIndex
:indexPath.
row
];
cell.
imageView
.
image
= [
UIImage
imageNamed
:
@"creme_brelee.jpg"
];
return
cell;
}
上面代碼中,我們添加了代碼行,指示UITableView在每一行顯示creme_brelee.jpg縮略圖。顯然,為了顯示不同的圖片,我們需要更改這一行代碼。之前解釋過(guò),在每一行數(shù)據(jù)顯示之前,iOS自動(dòng)調(diào)用一次cellForRowAtIndexPath方法。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
查看該方法的參數(shù),在調(diào)用的時(shí)候,傳入indexPath參數(shù)。indexPath 參數(shù)包包含了數(shù)據(jù)行的行編號(hào)(也就是節(jié)點(diǎn)編號(hào))。你可以使用indexPath.row屬性獲知當(dāng)前指向的行。和數(shù)組一樣,數(shù)據(jù)行從0開(kāi)始。也就是說(shuō),indexPath.row屬性針對(duì)表的第一行返回0.
為了顯示不同的縮略圖,我們將添加一個(gè)
新的數(shù)據(jù)(如thumbnails),存放縮略圖的文件名稱(chēng):
@implementation
SimpleTableViewController
{
? ?
NSArray
* tableData;
? ?
NSArray
* thumbnails;
? ?
NSString
* prepTime;
? ?
NSArray
* time;
}
?
?
- (
void
)viewDidLoad
{
? ? [
super
viewDidLoad
];
? ?
//Initialize table data
? ?
tableData
= [
NSArray
arrayWithObjects
:
@"Egg Benedict"
,
@"Mushroom Risotto"
,
@"Full Breakfast"
,
@"Hamburger"
,
@"Ham and Egg sandwith"
,
@"Creme Brelee"
,
@"White Chcolate Dount"
,
@"Starbucks Coffee"
,
@"Vegetable Curry"
,
@"Instant Noodle with Egg"
,
@"Noodle with BBQ Pork"
,
@"Japanese Noodle with Pork"
,
@"Green Tea"
,
@"Thai Shrimp Cake"
,
@"Angry Birds Cake"
,
@"Ham and Cheese Panini"
,
nil
];
?
? ?
//Initialize thumbnails
? ?
thumbnails
= [
NSArray
arrayWithObjects
:
@"egg_benedict.jpg"
,
@"mushroom_risotto.jpg"
,
@"full_breakfast.jpg"
,
@"hamburger.jpg"
,
@"ham_and_egg_sandwich.jpg"
,
@"creme_brelee.jpg"
,
@"white_chocolate_donut.jpg"
,
@"starbucks_coffee.jpg"
,
@"vegetable_curry.jpg"
,
@"instant_noodle_with_egg.jpg"
,
@"noodle_with_bbq_pork.jpg"
,
@"japanese_noodle_with_pork.jpg"
,
@"green_tea.jpg"
,
@"thai_shrimp_cake.jpg"
,
@"angry_birds_cake.jpg"
,
@"ham_and_cheese_panini.jpg"
,
nil
];
?
? ??
//Initialize prepTime
? ?
prepTime
=
@"PrepTime:"
;
?
? ? //Initialize time
? ?
time
= [
NSArray
arrayWithObjects
:
@"30 min"
,
@"20 min"
,
@"10 min"
,
@"40 min"
,
@"50 min"
,
@"70 min"
,
@"90 min"
,
@"30 min"
,
@"30 min"
,
@"30 min"
,
@"30 min"
,
@"30 min"
,
@"30 min"
,
@"30 min"
,
@"30 min"
,
@"30 min"
,
nil
];
}
從上面的代碼可以看出,我們初始化thumbnails數(shù)組位縮略圖文件名列表。圖片順序和tableData數(shù)組記錄保持一致。
圖片包見(jiàn)附件。
最后,更改cellForRowAtIndexPath方法的代碼行:
cell.imageView.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
2.[thumbnails objectAtIndex:indexPath.row] ?有什么用途?
該代碼負(fù)責(zé)位特定行檢索縮略圖的文件名。對(duì)第一行,indexPath.row 屬性返回0, 我們使用objectAtIndex方法,從thumbnails 數(shù)組獲得第一張圖片(如 egg_benedict.jpg)
在保存所有更改之后,再次運(yùn)行A pp,界面效果如下:
?
3.定制表視圖單元格
顯示效果如下:
?
4.設(shè)計(jì)單元格
在項(xiàng)目導(dǎo)航欄中,右擊SimpleTable文件夾,并選擇New File...。
為了設(shè)計(jì)我們自己的單元格,我們需要為單元格創(chuàng)建一個(gè)新的Interface Builder 文件。針對(duì)這個(gè)例子,我們僅需要從一個(gè)Empty的用戶界面開(kāi)始,點(diǎn)擊Next按鈕繼續(xù)。
在彈出選擇device family 窗口中,選擇iPhone,并點(diǎn)擊Next按鈕繼續(xù)。保存文件為SimpleTableCell.
在創(chuàng)建文件之后,可以在項(xiàng)目導(dǎo)航欄可以看到這個(gè)文件,選擇SimpleTableCell.xib文件切換到Interface Builder窗口。
下面,我們將設(shè)計(jì)定制單元格的用戶界面。
在對(duì)象庫(kù)(Object Library)中,選擇Table View Cell 控件,并拖拽到Interface Builder窗口的設(shè)計(jì)區(qū)域。
為了容納大尺寸的縮略圖,我們需要更改單元格的高度。按住單元格的底部或頂部邊緣,拖拉到78高度。
另外一個(gè)方法是,你可以通過(guò)Size Inspector 窗口來(lái)更改高度:
接著,選擇工具區(qū)域(Utility Area)上部分的Attribute Inspector 窗口,設(shè)置定制單元格的Identifier屬性值為:SimpleTableCell.這個(gè)Identifier將在后面代碼用到。
在配置好Table Cell View 之后,我們將放置其他控件在里面。選擇 Image View 控件,并拖拽到Table Cell View里面。
圖像視圖控件用來(lái)顯示縮略圖,我們可以通過(guò)改變控件尺寸,以適合單元格的大小。
我們?cè)O(shè)置圖像控件的高度和寬度為69像素
接著,我們添加三個(gè)標(biāo)簽Lables 控件,Name, Prep Time 和 Tiime。 Name 標(biāo)簽顯示菜譜名稱(chēng);Prep Time 是一個(gè)靜態(tài)標(biāo)簽,顯示文本Prep Time (準(zhǔn)備時(shí)間); 最后,Time標(biāo)簽是一個(gè)動(dòng)態(tài)標(biāo)簽,顯示特定菜譜的實(shí)際準(zhǔn)備時(shí)間。
添加Label 控件,從對(duì)象庫(kù)(Object Library) 選擇 Label 控件,拖拽到單元格。雙擊Label 更改其名稱(chēng)
選擇Label,然后選擇Attribute Inspector 窗口,在該窗口,你可以修改Font設(shè)置和最小化字體大小,同時(shí),還可以更改字體顏色和對(duì)齊方式。
最終設(shè)計(jì)的UI如下圖所示:
?
5.為定制單元格創(chuàng)建類(lèi)
目前為止,我們已經(jīng)設(shè)計(jì)好了表單元格,但是如何改變定制單元格的標(biāo)簽?zāi)兀?
我們將位定制的表視圖創(chuàng)建一個(gè)新類(lèi),這個(gè)類(lèi)表示定制單元格的底層數(shù)據(jù)
和之前一一樣,右擊項(xiàng)目欄中SimpleTable 文件夾,選擇New File...
接著Xcode彈出一窗口,選擇Cocoa Touch 下面的 Object-C class, 點(diǎn)擊Next
輸入SimpleTableCell 作為類(lèi)名,并選擇UITableViewCell 作為 Subclass of 下拉選項(xiàng)。
點(diǎn)擊next,點(diǎn)擊Create按鈕。
Xcode 應(yīng)該在項(xiàng)目導(dǎo)航欄中創(chuàng)建了2個(gè)文件:SimpleTableCell.h 和 SimpleTableCell.m。
SimpleTableCell 類(lèi)作為定制單元格的數(shù)據(jù)模型。在單元格中,有3個(gè)值是需要變更的:縮略圖、菜譜名稱(chēng)標(biāo)簽和時(shí)間標(biāo)簽。在類(lèi)中,我們將添加3個(gè)屬性,分別表示這些動(dòng)態(tài)值。
打開(kāi)SimpleTableCell.h 文件,在@end代碼前面添加如下屬性:
@property
(
nonatomic
,
weak
)
IBOutlet
UILabel
*nameLabel;
?
@property
(
nonatomic
,
weak
)
IBOutlet
UILabel
*prepTimeLabel;
?
@property
(
nonatomic
,
weak
)
IBOutlet
UIImageView
*thumbnailImageView;
?
@property
(
nonatomic
,
weak
)
IBOutlet
UILabel
*time;
6.Property 和 Outlet
上述代碼定義了三個(gè)實(shí)例變量,下面會(huì)用來(lái)和Interface Builder 中的表視圖單元格進(jìn)行關(guān)聯(lián)。
關(guān)鍵字@property 用來(lái)在類(lèi)中定義一個(gè)屬性:
@property(attibutes) type name;
關(guān)于前面的代碼,weak 和 nonatomic 是 property 的特性。 UILabel 和 UIImageView 是類(lèi)型,
nameLabel, prepTimeLabel 和 thumbnailImageView是變量名稱(chēng)。
IBOutlet :你可以將IBOutlet理解為一個(gè)指示符(indicator). 為了關(guān)聯(lián)實(shí)例變量和表視圖單元格中的文件,我們使用IBOutlet關(guān)鍵字,讓Interface Builder 知道它們?cè)试S建立連接。隨后,你將看到如何在這些Outlets 和Interface Builder 中的對(duì)象建立連接。
現(xiàn)在,打開(kāi)SimpleTableCell.m 文件,跟隨在@implementation SimpleTableCell 代碼行下面,添加如下代碼:
@synthesize
nameLabel = _nameLabel;
?
@synthesize
prepTimeLabel = _prepTimeLabel;
?
@synthesize
thumbnailImageView = _thumbnailImageView;
?
@synthesize
time = _time;
7.@synthesize指令
@synthesize 關(guān)鍵字告訴編譯器自動(dòng)生成代碼,用來(lái)訪問(wèn)前面定義的屬性。如過(guò)你忘記包含這些指令,Xcode 將拋出異常
8.建立連接
選擇SimpleTableCell.xib 文件,返回Interface Builder 界面。現(xiàn)在,我們將在此類(lèi)的屬性(或?qū)嵗兞浚┖徒缑嫔系腖abel、ImageView控件上建立連接。
首先,選擇單元格,并在Identity Inspector 窗口中,選擇類(lèi)SimpleTableCell.這里將關(guān)聯(lián)單元格視圖(cell view)和前面創(chuàng)建的定制類(lèi)。
現(xiàn)在,我們將和屬性建立連接。右擊Objects下面的SimpleTableCell, 顯示Outlets 監(jiān)視器(inspector).點(diǎn)擊并按住nameLabel右側(cè)的圓形圖標(biāo),拖拉到Label - Name 對(duì)象上。 Xcode 自動(dòng)建立它們之間的連接。
重復(fù)上面的步驟,為prepTimeLabel 和 thumbnailImageView 建立連接。
(1)連接prepTimeLabel 和 Label - Time 對(duì)象;
(2)連接thumbnailImageView 和 ImageView 對(duì)象;
9.更新SimpleTableViewController
我們已經(jīng)完成了定制表視圖單元格的設(shè)計(jì)和編碼工作,最后,我們要做的更新是 - 在SimpleTableViewController 中使用定制單元格。
再次訪問(wèn)SimpleTableViewController.m中用來(lái)創(chuàng)建表視圖行的代碼
我們使用默認(rèn)的表視圖單元格(如UITableViewCell)來(lái)顯示表元素。為了使用我們之前創(chuàng)建的定制單元格,我們需要?jiǎng)?chuàng)建SimpleTableView.m 中的這部分代碼,如下所示:
- (
UITableViewCell
*)tableView:(
UITableView
*)tableView cellForRowAtIndexPath:(
NSIndexPath
*)indexPath
{
? ?
static
NSString
*simpleTableIdentifier =
@"SimpleTableCell"
;
?
? ?
SimpleTableCell
*cell = (
SimpleTableCell
*)[tableView
dequeueReusableCellWithIdentifier
:simpleTableIdentifier];
?
? ?
if
(cell ==
nil
) {
? ? ? ?
NSArray
*nib = [[
NSBundle
mainBundle
]
loadNibNamed
:
@"SimpleTableCell"
owner
:
self
options
:
nil
];
? ? ? ? cell = [nib
objectAtIndex
:
0
];
? ? }
? ? cell.
nameLabel
.
text
= [
tableData
objectAtIndex
:indexPath.
row
];
? ? cell.
thumbnailImageView
.
image
= [
UIImage
imageNamed
:[
thumbnails
objectAtIndex
:indexPath.
row
]];
? ??cell.
prepTimeLabel
.
text
=
prepTime
;
? ??cell.
time
.
text
= [
time
objectAtIndex
:indexPath.
row
];
?
? ?
return
cell;
}
?
然后,在更新好代碼之后,Xcode檢測(cè)到一些錯(cuò)誤,并顯示在源碼編輯器中:
?
這是因?yàn)槲覀兩僖肧impleTableCell.h 頭文件。
?
最后,因?yàn)楸韱卧竦母叨雀臑?8,因此在@end代碼行之前添加如下代碼:
?
?
- (
CGFloat
)tableView:(
UITableView
*)tableView heightForRowAtIndexPath:(
NSIndexPath
*)indexPath
{
? ?
return
78
;
}
現(xiàn)在,點(diǎn)擊Run按鈕,你的SimpleTableApp運(yùn)行界面如下圖所示:
?
?
?
?
【一步一步學(xué)IOS5 】 定制UITableView表視圖單元格