iOS UITableView 與 UITableViewController實例詳解
很多應(yīng)用都會在界面中使用某種列表控件:用戶可以選中、刪除或重新排列列表中的項目。這些控件其實都是UITableView 對象,可以用來顯示一組對象,例如,用戶地址薄中的一組人名。
UITableView 對象雖然只能顯示一行數(shù)據(jù),但是沒有行數(shù)限制。
•編寫新的應(yīng)用程序 JXHomepwner 應(yīng)用
創(chuàng)建應(yīng)用,填寫基本信息
•UITableViewController
UITableView 是視圖。我們知道 模型-視圖-控制器(Model-View-Controller),他是我們必須遵守的一種設(shè)計模式。其含義是,應(yīng)用創(chuàng)建的任何一個對象,其類型必定是以下三種類型中的一種。
1. 模型:負(fù)責(zé)存儲數(shù)據(jù),與用戶界面無關(guān)。
2. 視圖:負(fù)責(zé)顯示界面,與模型對象無關(guān)。
3. 控制器:負(fù)責(zé)確保視圖對象和模型對象的數(shù)據(jù)保持一致。
一般來說,作為視圖對象的 UITableView 不應(yīng)該負(fù)責(zé)處理應(yīng)用的邏輯或數(shù)據(jù)。當(dāng)在應(yīng)用中使用 UITableView 對象的時候,必須考慮如何大啊呸其他的對象,與 UITableView 對象一起工作:
通常情況下,要通過某個視圖控制器對象來創(chuàng)建和釋放 UITableView 對象,并負(fù)責(zé)顯示或者隱藏視圖。
UITableView 對象要有數(shù)據(jù)源才能正常工作。UITableView 對象會向數(shù)據(jù)源查詢要顯示的行數(shù),顯示表格行所需要的數(shù)據(jù)和其他所需要的數(shù)據(jù)。沒有數(shù)據(jù)源的 UITableView 對象只是空殼。凡是遵守 UITableViewDataSource 協(xié)議的對象,都可以成為 UITableView 對象的數(shù)據(jù)源(即dataSource屬性所指向的對象)。
通常情況下,要為 UITableView 對象設(shè)置委托對象,以便能在該對象發(fā)生特定事件的時候做出相應(yīng)的處理。凡是遵守 UITableViewDelegate 協(xié)議的對象,都可以成為 UITableView 對象的委托對象。
UITableViewController 對象可以扮演以上全部角色,包括視圖控制器對象、數(shù)據(jù)源和委托對象。
UITableViewController 是 UIViewController 的子類,所以也有 view 屬性。UITableViewController 對象的 view 屬性指向一個 UITableView 對象,并且這個對象由 UITableViewController 對象負(fù)責(zé)設(shè)置和顯示。UITableViewController 對象會在創(chuàng)建 UITableView 對象后,為這個 UITableView 對象的 dataSource 和 delegate 賦值,并指向自己。
• 創(chuàng)建 UITableViewController 子類
下面要為我們創(chuàng)建的程序編寫一個 UITableViewController 子類。
UITableViewController 的指定初始化方法是 initWithStyle: 調(diào)用 initWithStyle: 時要傳入一個類型作為 UITableViewStyle 的常熟,該常熟決定了 UITableView 對象的風(fēng)格。目前可以使用的 UITableViewStyle 常量有兩個,即 UITableViewStylePlain 和 UITableViewStyleGrouped 。
現(xiàn)在將 UITableViewController 的指定初始化方法改為 init: ,為此時需要遵守兩條規(guī)則:
1. 在新的指定初始化方法中調(diào)用父類的指定初始化方法。
2. 覆蓋父類的初始化方法,調(diào)用新的指定初始化方法。
#import "JXItemsViewController.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 調(diào)用父類的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
@end
實現(xiàn)以上兩個初始化方法之后,可以確保無論向新創(chuàng)建的 JXItemsViewController 對象發(fā)送哪一個初始化方法,初始化后的對象都會使用我們指定的風(fēng)格。
接下來代碼如下:
#import "AppDelegate.h"
#import "JXItemsViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
// 添加初始化代碼
// 創(chuàng)建 JXItemsViewController 對象
JXItemsViewController * itemsViewController = [[JXItemsViewController alloc] init];
// 將 JXItemsViewController 的標(biāo)示圖加入窗口
self.window.rootViewController = itemsViewController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
構(gòu)建并運行應(yīng)用我們確實能在屏幕上看到 UITableView 對象。JXItemsViewController 作為 UITableViewController 的子類,集成了 view 方法。 view 方法會調(diào)用 loadView 方法,如果視圖不存在,則 loadView 方法會創(chuàng)建并載入一個空的視圖。
下面我們要為 UITableView 設(shè)置內(nèi)容。
新建 JXItem 類
#import <Foundation/Foundation.h>
@interface JXItem : NSObject
/** 創(chuàng)建日期 */
@property (nonatomic,strong,readonly) NSDate * createDate;
/** 名稱 */
@property (nonatomic,strong) NSString * itemName;
/** 編號 */
@property (nonatomic,strong) NSString * serialnumber;
/** 價值 */
@property (nonatomic,assign) NSInteger valueInDollars;
/** JXImageStore中的鍵 */
@property (nonatomic,strong) NSString * itemKey;
+ (instancetype)randomItem;
/**
* JXItem類指定的初始化方法
* @return 類對象
*/
- (instancetype)initWithItemName:(NSString *)name
valueInDollars:(NSInteger)value
serialNumber:(NSString *)sNumber;
- (instancetype)initWithItemName:(NSString *)name;
@end
#import "JXItem.h"
@implementation JXItem
+ (instancetype)randomItem {
// 創(chuàng)建不可變數(shù)組對象,包含三個形容詞
NSArray * randomAdjectiveList = @[
@"Fluffy",
@"Rusty",
@"Shiny"
];
// 創(chuàng)建不可變數(shù)組對象,包含三個名詞
NSArray * randomNounList = @[
@"Bear",
@"Spork",
@"Mac"
];
// 根據(jù)數(shù)組對象所含的對象的個數(shù),得到隨機索引
// 注意:運算符%是模運算符,運算后得到的是余數(shù)
NSInteger adjectiveIndex = arc4random() % randomAdjectiveList.count;
NSInteger nounIndex = arc4random() % randomNounList.count;
// 注意,類型為NSInteger 的變量不是對象
NSString * randomName = [NSString stringWithFormat:@"%@ %@",randomAdjectiveList[adjectiveIndex],randomNounList[nounIndex]];
NSInteger randomValue = arc4random_uniform(100);
NSString * randomSerialNumber = [NSString stringWithFormat:@"%c%c%c%c",
'0' + arc4random_uniform(10),
'A' + arc4random_uniform(26),
'0' + arc4random_uniform(10),
'A' + arc4random_uniform(26)];
JXItem * newItem = [[self alloc] initWithItemName:randomName
valueInDollars:randomValue
serialNumber:randomSerialNumber];
return newItem;
}
- (NSString *)description {
NSString * descriptionString = [NSString stringWithFormat:@"%@ (%@):Worth $%zd, recorded on %@",self.itemName,self.serialnumber,self.valueInDollars,self.createDate];
return descriptionString;
}
- (instancetype)initWithItemName:(NSString *)name
valueInDollars:(NSInteger)value
serialNumber:(NSString *)sNumber {
// 調(diào)用父類的指定初始化方法
self = [super init];
// 父類的指定初始化方法是否成功創(chuàng)建了對象
if (self) {
// 為實例變量設(shè)置初始值
_itemName = name;
_valueInDollars = value;
_serialnumber = sNumber;
// 設(shè)置_createDate為當(dāng)前時間
_createDate = [NSDate date];
// 創(chuàng)建一個 NSUUID 對象
NSUUID * uuid = [[NSUUID alloc] init];
NSString * key = [uuid UUIDString];
_itemKey = key;
}
// 返回初始化后的對象的新地址
return self;
}
- (instancetype)initWithItemName:(NSString *)name {
return [self initWithItemName:name valueInDollars:0 serialNumber:@""];
}
- (instancetype)init {
return [self initWithItemName:@"Item"];
}
- (void)dealloc {
NSLog(@"Destoryed:%@",self);
}
@end
•UITableView 數(shù)據(jù)源
創(chuàng)建JXItemStore
JXItemStore 對象是一個單例,也就是說,每個應(yīng)用只會有一個這種類型的對象。如果應(yīng)用嘗試創(chuàng)建另一個對象,JXItemStore類就會返回已經(jīng)存在的那個對象。當(dāng)某個程序要在很多不同的代碼段中使用同一個對象時,將這個對象設(shè)置為單例是一種很好的設(shè)計模式,只需要向該對象的類發(fā)送特定的方法,就可以得到相同的對象。
#import <Foundation/Foundation.h>
@interface JXItemStore : NSObject
// 注意,這是一個類方法,前綴是+
+ (instancetype)sharedStore;
@end
在 JXItemStore 類收到 sharedStore 消息后,會檢查自己是否已經(jīng)創(chuàng)建 JXItemStore 的單例對象。如果已經(jīng)創(chuàng)建,就返回自己已經(jīng)創(chuàng)建的對象,否則就需要先創(chuàng)建,然后再返回。
#import "JXItemStore.h"
@implementation JXItemStore
// 單粒對象
+ (instancetype)sharedStore {
static JXItemStore * sharedStore = nil;
// 判斷是否需要創(chuàng)建一個 sharedStore 對象
if (!sharedStore) {
sharedStore = [[self alloc] init];
}
return sharedStore;
}
@end
這段代碼將 sharedStore 指針聲明了 靜態(tài)變量。當(dāng)某個定義了靜態(tài)變量的方法返回時,程序不會釋放相應(yīng)的變量。靜態(tài)變量和全局變量一樣,并不是保存在棧中的。
sharedStore 變量的初始值為 nil。當(dāng)程序第一次執(zhí)行 sharedStore 方法時,會創(chuàng)建一個 JXItemStore 對象,并將新創(chuàng)建的對象的地址賦值給 sharedStore 變量。當(dāng)程序再次執(zhí)行 sharedStore 方法時,不管是第幾次,其指針總是指向最初創(chuàng)建的那個對象。因為指向 JXItemStore 對象的 sharedStore 變量是強引用,且程序永遠不會釋放該變量,所以 sharedStore 變量所指向的 JXItemStore 對象永遠也不會被釋放。
JXItemsViewController 需要創(chuàng)建一個新的 JXItem 對象時會向 JXItemStore 對象發(fā)送消息,收到消息的 JXItemStore 對象會創(chuàng)建一個 JXItem 對象并將其保存到一個 JXItem 數(shù)組中,之后 JXItemsViewController 可以通過該數(shù)組獲取所有 JXItem 對象,并使用這些對象填充自己的表視圖。
#import <Foundation/Foundation.h> @class JXItem; @interface JXItemStore : NSObject /** 存放 JXItem 對象數(shù)組 */ @property (nonatomic,readonly) NSArray * allItem; // 注意,這是一個類方法,前綴是+ + (instancetype)sharedStore; - (JXItem *)createItem; @end
在實現(xiàn)文件中編輯。但是我們需要注意,在我們的應(yīng)用中將使用 JXItemStore 管理 JXItem 數(shù)組-包括添加、刪除和排序。因此,除 JXItemStore 之外的類不應(yīng)該對 JXItem 數(shù)組做這些操作。在 JXItemStore 內(nèi)部,需要將 JXItem 數(shù)組定義為可變數(shù)組。而對其他類來說,JXItem 數(shù)組則是不可變的數(shù)組。這是一種常見的設(shè)計模式,用于設(shè)置內(nèi)部數(shù)據(jù)的訪問權(quán)限:某個對象中有一種可修改的數(shù)據(jù),但是除該對象本身之外,其他對象只能訪問該數(shù)據(jù)而不能修改它。
#import "JXItemStore.h"
#import "JXItem.h"
@interface JXItemStore ()
/** 可變數(shù)組,用來操作 JXItem 對象 */
@property (nonatomic,strong) NSMutableArray * privateItems;
@end
@implementation JXItemStore
// 單粒對象
+ (instancetype)sharedStore {
static JXItemStore * sharedStore = nil;
// 判斷是否需要創(chuàng)建一個 sharedStore 對象
if (!sharedStore) {
sharedStore = [[self alloc] init];
}
return sharedStore;
}
- (NSArray *)allItem {
return self.privateItems;
}
#pragma mark - 懶加載
- (NSMutableArray *)privateItems{
if (_privateItems == nil) {
_privateItems = [[NSMutableArray alloc] init];
}
return _privateItems;
}
@end
allItem 方法的返回值是 NSArray 類型,但是方法體中返回的是 NSMutableArray 類型的對象,這種寫法是正確的,因為NSMutableArray 是 NSArray 子類。
這種寫法可能會引起一個問題:雖然頭文件中將 allItem 的類型聲明為 NSArray ,但是其他對象調(diào)用 JXItemStore 的 allItem 方法時,得到的一定是一個 NSMutableArray 對象。
使用像 JXItemStore 這樣的類時,應(yīng)該遵守其頭文件中的聲明使用類的屬性和方法。 例如,在 JXItemStore 頭文件中,因為 allItem 屬性的類型是 NSArray ,所以應(yīng)該將其作為 NASrray 類型的對象使用。如果將 allItem 轉(zhuǎn)換為 NSMutableArray 類型并修改其內(nèi)容,就違反了 JXItemStore 頭文件中的聲明。可以通過覆蓋 allItem 方法避免其他類修改 allItem 。
#import "JXItemStore.h"
#import "JXItem.h"
@interface JXItemStore ()
/** 可變數(shù)組,用來操作 JXItem 對象 */
@property (nonatomic,strong) NSMutableArray * privateItems;
@end
@implementation JXItemStore
// 單粒對象
+ (instancetype)sharedStore {
static JXItemStore * sharedStore = nil;
// 判斷是否需要創(chuàng)建一個 sharedStore 對象
if (!sharedStore) {
sharedStore = [[self alloc] init];
}
return sharedStore;
}
- (NSArray *)allItem {
return [self.privateItems copy];
}
- (JXItem *)createItem {
JXItem * item = [JXItem randomItem];
[self.privateItems addObject:item];
return item;
}
#pragma mark - 懶加載
- (NSMutableArray *)privateItems{
if (_privateItems == nil) {
_privateItems = [[NSMutableArray alloc] init];
}
return _privateItems;
}
@end
實現(xiàn)數(shù)據(jù)源方法
#import "JXItemsViewController.h"
#import "JXItem.h"
#import "JXItemStore.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 調(diào)用父類的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
for (NSInteger i=0; i<5; i++) {
[[JXItemStore sharedStore] createItem];
}
}
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
@end
當(dāng)某個 UITableView 對象要顯示表格內(nèi)容時,會向自己的數(shù)據(jù)源(dataSource 屬性所指向的對象)發(fā)送一系列消息,其中包括必須方法和可選方法。
@required - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; // Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier: // Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls) - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; @optional - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; // Default is 1 if not implemented - (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section; // fixed font style. use custom view (UILabel) if you want something different - (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section; // Editing // Individual rows can opt out of having the -editing property set for them. If not implemented, all rows are assumed to be editable. - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath; // Moving/reordering // Allows the reorder accessory view to optionally be shown for a particular row. By default, the reorder control will be shown only if the datasource implements -tableView:moveRowAtIndexPath:toIndexPath: - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath; // Index - (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView __TVOS_PROHIBITED; // return list of section titles to display in section index view (e.g. "ABCD...Z#") - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index __TVOS_PROHIBITED; // tell table which section corresponds to section title/index (e.g. "B",1)) // Data manipulation - insert and delete support // After a row has the minus or plus button invoked (based on the UITableViewCellEditingStyle for the cell), the dataSource must commit the change // Not called for edit actions using UITableViewRowAction - the action's handler will be invoked instead - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath; // Data manipulation - reorder / moving support - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath; @end
實現(xiàn)行數(shù)代碼
#import "JXItemsViewController.h"
#import "JXItem.h"
#import "JXItemStore.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 調(diào)用父類的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
for (NSInteger i=0; i<5; i++) {
[[JXItemStore sharedStore] createItem];
}
}
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[[JXItemStore sharedStore] allItem] count];
}
@end
UITableViewDataSource 協(xié)議中的另外一個必須實現(xiàn)的方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
在此之前,我們需要先了解另一個類:UITableViewCell
•UITableViewCell 對象
表視圖所顯示的每一行都是一個獨立的視圖,這些視圖是 UITableViewCell 對象。其對象還有一個子視圖:contentView 。contentView 也包含了很多子視圖,他的子視圖構(gòu)成 UITableViewCell 對象的主要外觀。此外, UITableViewCell 對象還可以顯示一個輔助指示圖。輔助指示視圖的作用是顯示一個指定的圖標(biāo),用于向用戶提示 UITableViewCell 對象可以執(zhí)行的動作。這些圖標(biāo)包括勾起標(biāo)記、展開圖標(biāo)或中間有v形團的藍色圓點。其默認(rèn)是 UITableViewCellAccessoryNone 。
在創(chuàng)建 UITableViewCell 對象時,可以選擇不同的風(fēng)格來決定 UITableViewCell 對象顯示。
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
UITableViewCellStyleDefault, // Simple cell with text label and optional image view (behavior of UITableViewCell in iPhoneOS 2.x)
UITableViewCellStyleValue1, // Left aligned label on left and right aligned label on right with blue text (Used in Settings)
UITableViewCellStyleValue2, // Right aligned label on left with blue text and left aligned label on right (Used in Phone/Contacts)
UITableViewCellStyleSubtitle // Left aligned label on top and left aligned label on bottom with gray text (Used in iPod).
}; // available in iPhone OS 3.0
創(chuàng)建并獲取 UITableViewCell 對象
下面我們主要對 tableView: cellForRowAtIndexPath: 方法進行改寫。首先我們需要將 JXItem 數(shù)據(jù)跟 UITableViewCell 對象對應(yīng)起來。在方法中有一個實參是 NSIndexPath 對象,該對象包含兩個屬性 section(段) 和 row(行) 。當(dāng) UITableView 對象向其數(shù)據(jù)源發(fā)送 tableView: cellForRowAtIndexPath: 消息時,其目的是獲取顯示第 section 個表格段、第 row 行數(shù)據(jù)的 UITableViewCell 對象。
#import "JXItemsViewController.h"
#import "JXItem.h"
#import "JXItemStore.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 調(diào)用父類的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
for (NSInteger i=0; i<15; i++) {
[[JXItemStore sharedStore] createItem];
}
}
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[[JXItemStore sharedStore] allItem] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 創(chuàng)建 UITableViewCell 對象,風(fēng)格使用默認(rèn)風(fēng)格
UITableViewCell * cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"UITableViewCell"];
// 獲取 allItem 的第 n 個 JXItem 對象
// 然后將該 JXItem 對象的描述信息賦值給 UITableViewCell 對象的 textLabel
// 這里的 n 是該 UITableViewCell 對象所對應(yīng)的表格索引
NSArray * items = [[JXItemStore sharedStore] allItem];
JXItem * item = items[indexPath.row];
cell.textLabel.text = [item description];
return cell;
}
@end
構(gòu)建并運行
重用UITableViewCell對象
iOS設(shè)備內(nèi)存是有限的,如果某個 UITableView 對象要顯示大量的記錄,并且要針對每條記錄創(chuàng)建相應(yīng)的 UITableViewCell 對象,就會很快耗盡iOS設(shè)備內(nèi)存。
在 UITableView 上存在大量可優(yōu)化的地方,其中最重要的就是關(guān)于 UITableViewCell 復(fù)用問題。因為當(dāng)我們滑動界面是,大多數(shù)的 cell表格都會移出窗口,移出窗口的 UITableViewCell 對象放入 UITableViewCell 對象池,等待重用。當(dāng) UITableView 對象要求數(shù)據(jù)源返回某個 UITableViewCell 對象時,就可以先查看對象池。如果有未使用的 UITableViewCell 對象,就可以用新的數(shù)據(jù)配置這個 UITableViewCell 對象,然后將其返回給 UITableView 對象,從而避免了創(chuàng)建新的對象,可以極大的優(yōu)化內(nèi)存。
但是這里還會有一個問題:如果我們在 UITableView 對象中創(chuàng)建了不同的 UITableViewCell 表格,用來展示不同的信息。那么這時候 UITableViewCell 對象池中的對象就會存在不同的類型,那么 UItableView 就有可能會得到錯誤的類型的 UITableViewCell 對象。鑒于上述原因,必須保證 UITableView 對象能夠得到正確的指定類型的 UITableViewCell 對象,這樣才能確定返回的對象會擁有哪些屬性和方法。
從 UITableViewCell 對象池獲取對象時,無需關(guān)心取回的是否是某個特性的對象,因為無論取回來的是哪個對象,都要重新設(shè)置數(shù)據(jù)。真正要關(guān)心的是取回來的對象是否是某個特性的類型。每個 UITableViewCell 對象都有一個類型為 NSString 的 reuseIdentifier 屬性。當(dāng)數(shù)據(jù)源向 UITableView 對象獲取可重用的 UITableViewCell 對象時,可傳入一個字符串并要求 UITableView 對象返回相應(yīng)的 UITableViewCell 對象。
#import "JXItemsViewController.h"
#import "JXItem.h"
#import "JXItemStore.h"
@interface JXItemsViewController ()
@end
@implementation JXItemsViewController
- (instancetype)init {
// 調(diào)用父類的指定初始化方法
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
for (NSInteger i=0; i<15; i++) {
[[JXItemStore sharedStore] createItem];
}
}
return self;
}
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [self init];
}
- (void)viewDidLoad {
[super viewDidLoad];
// 向控制器注冊
[self.tableView registerClass:[UITableViewCell class]
forCellReuseIdentifier:@"UITableViewCell"];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[[JXItemStore sharedStore] allItem] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 創(chuàng)建 UITableViewCell 對象,風(fēng)格使用默認(rèn)風(fēng)格
UITableViewCell * cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"UITableViewCell"];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"
forIndexPath:indexPath];
// 獲取 allItem 的第 n 個 JXItem 對象
// 然后將該 JXItem 對象的描述信息賦值給 UITableViewCell 對象的 textLabel
// 這里的 n 是該 UITableViewCell 對象所對應(yīng)的表格索引
NSArray * items = [[JXItemStore sharedStore] allItem];
JXItem * item = items[indexPath.row];
cell.textLabel.text = [item description];
return cell;
}
@end
以上所述是小編給大家介紹的iOS UITableView 與 UITableViewController實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- iOS應(yīng)用開發(fā)中UITableView的分割線的一些設(shè)置技巧
- 詳解iOS開發(fā)中UITableview cell 頂部空白的多種設(shè)置方法
- IOS UITableViewCell詳解及按鈕點擊事件處理實例
- 改變iOS應(yīng)用中UITableView的背景顏色與背景圖片的方法
- iOS App中UITableView左滑出現(xiàn)刪除按鈕及其cell的重用
- 全面解析iOS應(yīng)用中自定義UITableViewCell的方法
- 詳解iOS開發(fā)中UItableview控件的數(shù)據(jù)刷新功能的實現(xiàn)
- IOS 開發(fā)之UITableView 刪除表格單元寫法
相關(guān)文章
iOS開發(fā)存儲應(yīng)用程序Info.plist知識全面詳解
這篇文章主要為大家介紹了iOS開發(fā)存儲應(yīng)用程序Info.plist知識全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06
IOS TextFiled與TextView 鍵盤的收起以及處理鍵盤遮擋
這篇文章主要介紹了IOS TextFiled與TextView 鍵盤的收起以及處理鍵盤遮擋的相關(guān)資料,需要的朋友可以參考下2016-12-12
IOS使用UICollectionView實現(xiàn)無限輪播效果
這篇文章主要為大家詳細(xì)介紹了IOS使用UICollectionView實現(xiàn)無限輪播效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-03-03
解析iOS開發(fā)中的FirstResponder第一響應(yīng)對象
這篇文章主要介紹了解析iOS開發(fā)中的FirstResponder第一響應(yīng)對象,包括View的FirstResponder的釋放問題,需要的朋友可以參考下2015-10-10

