背景知识

每个表都是UITableView的实例,表中的每一行都是UITableViewCell的实例。

TableView的种类

  • Grouped table
  • Plain table without index
  • Plain table with index

NSIndexPath

  • NSIndexPath.section 返回int,表示第几个Section
  • NSIndexPath.row 返回int,表示该Section下的第几行

UITableViewCell包含的元素

  • Image    (imageView.image)
  • Text Label (textLabel.text, textLabel.font)
  • Detail Text Label (detailTextLabel.text)

UITableViewCell样式

  • UITableViewCellStyleDefault   //左文,图(如果有则最左)
  • UITableViewCellStyleSubtitile   //左文,图(如果有则最左),detailText在Text下面
  • UITableViewCellStyleValue1        //左文,图(如果有则最左),detailText在最右
  • UITableViewCellStyleValue2        //左文,图(如果有则最左),detailText在Text右边

简单例子

StoryBoard拖入一个TableView,然后设置DataSource和Delegate为ViewController。
ViewController.h声明协议

#import <UIKit/UIKit.h>

@interface XYZViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>
@end

ViewController.m文件如下

//
// XYZViewController.m
// TableView
//
// Created by Norcy on 14-7-24.
// Copyright (c) 2014年 QQLive. All rights reserved.
// #import "XYZViewController.h" @interface XYZViewController ()
@property (strong, nonatomic)NSArray *array;
@end @implementation XYZViewController - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. self.array = [[NSArray alloc] initWithObjects:@"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", @"", nil];
} - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} #pragma mark -
#pragma mark Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return ;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.array count];
} #pragma mark Delegate Methods
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId = @"MyCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellId];
} cell.textLabel.text = self.array[indexPath.row]; UIImage *image = [UIImage imageNamed:@"1.png"]; cell.imageView.image = image; cell.detailTextLabel.text = @"Details"; return cell;
} - (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
return indexPath.row;
}
@end

代码说明

代码说明1:

static NSString *CellID = @"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellID];
}

从ReusableCell的队列中取出带有Identifier标识的Cell,如果Cell为空,则新创建一个。
ReusableCell队列是专门存放那些生成过的,但是后来由于滚动tableView而隐藏起来的cell。这样做可以节约资源。
注意CellIdentifier这个参数是可以自定义的,如果使用storyboard的话需要跟storyboard中的cell的Identifier相同。

  • dequeueReusableCellWithIdentifier: 可能返回nil(没有为TableView注册Cell的情况返回nil)
  • dequeueReusableCellWithIdentifier:forIndexPath: 不可能返回nil

所以如果使用dequeueReusableCellWithIdentifier:forIndexPath的话就不用检查nil的情况了。

But,以上这种写法已经过时了。推荐最新写法

[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CELL_ID];
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CELL_ID forIndexPath:indexPath];

如果TableView已经注册了Cell,那么dequeueReusableCellWithIdentifier:一定不为空;因为当系统从重用队列中取cell取不到的时候,会自动帮我们生成并初始化一个cell。

所以建议直接用registerClass:forCellReuseIdentifier:CELL_ID + dequeueReusableCellWithIdentifier:forIndexPath: 这个组合。

代码说明2:

- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
return indexPath.row;
}

设置缩进。

代码说明3:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == )
return nil;
else
return indexPath;
}

选中某行之前调用,返回nil表示该行不能被选择,返回indexPath表示可以继续选择(可以返回其他路径但最好不要更改用户的选择,所以一般返回nil或indexPath来表示禁止或允许某个选择)

代码说明4:

- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

选中某行之后调用,一般要调用deselectRowAtIndexPath

代码说明5:

cell.textLabel.font = [UIFont boldSystemFontOfSize:];

- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return ;
}

设置TableViewCell的行高以适应TableViewCell的字体

附录,联系人Demo(Based in IOS7.0) or 直接查看主要代码

//
// ViewController.m
// Contact
//
// Created by Norcy on 15/4/16.
// Copyright (c) 2015年 Norcy. All rights reserved.
// #import "ViewController.h" @interface ViewController ()
{
}
@property (strong, nonatomic) NSDictionary* names;
@property (strong, nonatomic) NSArray* keys;
@end NSMutableArray* filteredNames;
UISearchDisplayController* searchController;
static NSString* CELL_ID = @"MyCell"; @implementation ViewController - (void)viewDidLoad
{
[super viewDidLoad]; //Screen
int screenWidth = [[UIScreen mainScreen] bounds].size.width;
int screenHeight = [[UIScreen mainScreen] bounds].size.height; //Filter
filteredNames = [[NSMutableArray alloc] init]; //TableView
UITableView* tableView = [[UITableView alloc] initWithFrame:CGRectMake(, , screenWidth, screenHeight)]; [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CELL_ID]; tableView.delegate = self; tableView.dataSource = self; tableView.tag = ; UIEdgeInsets insets = tableView.contentInset; //设置与屏幕顶部的距离,防止被状态栏挡住 insets.top = ; [tableView setContentInset:insets]; //Search Bar
UISearchBar* searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(, , screenWidth, screenHeight / )]; tableView.tableHeaderView = searchBar; searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self]; searchController.delegate = self; searchController.searchResultsDataSource = self; //Names and Keys
NSString* path = [[NSBundle mainBundle] pathForResource:@"sortednames" ofType:@"plist"]; self.names = [NSDictionary dictionaryWithContentsOfFile:path]; self.keys = [[self.names allKeys] sortedArrayUsingSelector:@selector(compare:)]; [self.view addSubview:tableView];
} #pragma mark -
#pragma mark Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
{
if (tableView.tag == )
return [self.keys count];
else
return ;
} - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView.tag == )
{
NSString* key = self.keys[section];
NSArray* curSection = self.names[key];
return [curSection count];
}
else
return [filteredNames count];
} - (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section
{
if (tableView.tag == )
return self.keys[section];
else
return nil;
} - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CELL_ID forIndexPath:indexPath]; // UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CELL_ID]; // if (cell == nil)
// {
// NSLog(@"asd");
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CELL_ID];
// } if (tableView.tag == )
{
NSString* key = self.keys[indexPath.section]; NSArray* curSection = self.names[key]; cell.textLabel.text = curSection[indexPath.row];
}
else
cell.textLabel.text = filteredNames[indexPath.row]; return cell;
} #pragma mark Delegate Methods
//显示索引
- (NSArray*)sectionIndexTitlesForTableView:(UITableView*)tableView
{
if (tableView.tag == )
return self.keys;
else
return nil;
} - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
} #pragma mark Search Delegate Methods
- (void)searchDisplayController:(UISearchDisplayController*)controller didLoadSearchResultsTableView:(UITableView*)tableView
{
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CELL_ID];
} - (BOOL)searchDisplayController:(UISearchDisplayController*)controller shouldReloadTableForSearchString:(NSString*)searchString
{
[filteredNames removeAllObjects]; if (searchString.length > )
{
NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary* bindings) {
NSRange range = [evaluatedObject rangeOfString:searchString options:NSCaseInsensitiveSearch];
return range.location != NSNotFound;
}]; for (NSString* key in self.keys)
{
NSArray* matches = [self.names[key] filteredArrayUsingPredicate:predicate]; [filteredNames addObjectsFromArray:matches];
}
} return YES;
} @end

简单的TableView的更多相关文章

  1. IOS中TableView的使用(1) -创建一个简单的tableView

    创建一个简单的tableView: #import <UIKit/UIKit.h> /*tableView 一定要遵守这两个协议: UITableViewDataSource,UITabl ...

  2. 【转】ios tableView那些事(一)创建一个简单的tableView

    工作也有半年多了!几乎每个项目中的会用到tableview这个神奇而好用的控件,在学习和工作中都会看别人的博客!对我有很大的帮助,就如同站在巨人的肩膀上的感觉吧 哈哈!于是决定重新开始写博客,希望能帮 ...

  3. iOS学习笔记(5)——显示简单的TableView

    1. 创建工程 创建一个新的Xcode工程命名为SimpleTableTest. 删除main.storyboard文件和info.plist中有关storyboard的相关属性. 按command+ ...

  4. tableView

    Table View简单描述: 在iPhone和其他iOS的很多程序中都会看到Table View的出现,除了一般的表格资料展示之外,设置的属性资料往往也用到Table View,Table View ...

  5. iOS学习之Table View的简单使用

    Table View简单描述: 在iPhone和其他iOS的很多程序中都会看到Table View的出现,除了一般的表格资料展示之外,设置的属性资料往往也用到Table View,Table View ...

  6. TableView不显示没内容的Cell怎么办?

    类似这种,我不想让下面那些空的显示. 很简单: self.tableView.tableFooterView = [[UIView alloc] init]; 加完这句之后就变成了这样:

  7. Swift初窥--使用Swift实现TableView

    完毕Swift的语法关之后.来点实际的Task,第一个任务是写一个tableview,使用cocoaTouch里tableview这个经常使用的控件. 创建project.选择Swift语言 首先是用 ...

  8. OC开发_代码片段——代码编写简单的tableViewCell

    许久前写的简单的tableView例子,主要针对处理缓存.协议.数据源datasource.局部刷新等问题进行解析. 其实这是一篇不全面的记录,只是用来记录一些备忘的东西,更全面的是使用TablVie ...

  9. ***iOS学习之Table View的简单使用和DEMO示例(共Plain普通+Grouped分组两种)

    Table View简单描述: 在iPhone和其他iOS的很多程序中都会看到Table View的出现,除了一般的表格资料展示之外,设置的属性资料往往也用到Table View,Table View ...

随机推荐

  1. 算法笔记_095:蓝桥杯练习 拿糖果(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 妈妈给小B买了N块糖!但是她不允许小B直接吃掉. 假设当前有M块糖,小B每次可以拿P块糖,其中P是M的一个不大于根号下M的质因数.这时,妈 ...

  2. 算法笔记_087:蓝桥杯练习 9-1九宫格(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 问题描述 九宫格.输入1-9这9个数字的一种任意排序,构成3*3二维数组.如果每行.每列以及对角线之和都相等,打印1.否则打印0. 样例输出 与上面 ...

  3. LoadRunner+Android模所器实现抓包并调试本地服务端

    步骤就是 1:新建LR脚本.协议选择Mobile Application - HTTP/HTML 2:在record里选择第三个:Record Emulator........ 3:  选择下一步后, ...

  4. MySQL中 order by 与 limit 的执行顺序以及使用实例

    在 MySQL 执行查询的时候,我们可能既要对结果集进行排序又要限制行数,那么此时 order by 与 limit 的执行顺序是怎么样的呢? order by与limit的执行顺序是:先执行orde ...

  5. Eclipse Debug 使用

      Eclipse的debug模式:代码调试 * Eclipse或MyEclipse就是java的开发工具 * Eclipse开源的.免费的Java开发工具 * MyEclipse基于Eclipse开 ...

  6. php引用(&)变量引用,函数引用,对象引用和参数引用用法

    php引用(&)变量引用,函数引用,对象引用和参数引用用法   php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容.与C语 ...

  7. javascript解析器(引擎)

    The JavaScript interpreter in a browser is implemented as a single thread. javascript 引擎在浏览器中作为单线程实现 ...

  8. c语言中数组名和指针变量的区别

    编译器工作原理:在64位的计算机中,当创建一个指针变量时,计算机会为它分配8个字节的存储空间.但如果创建的是数组呢?计算机会为数组分配存储空间,但不会为数组变量分配任何空间,编译器仅在出现它的地方把它 ...

  9. Python学习之warn()函数

    warn()函数位于warnings模块中,用来发出警告,或者忽略它或引发异常. def warn(message, category=None, stacklevel=, source=None) ...

  10. poj 3017 Cut the Sequence(单调队列优化 )

    题目链接:http://poj.org/problem?id=3017 题意:给你一个长度为n的数列,要求把这个数列划分为任意块,每块的元素和小于m,使得所有块的最大值的和最小 分析:这题很快就能想到 ...