UITableView是UI Kit中非常重要的类,称为表视图,使用图表化的形式来展示数据及资源。
UITableView继承于UIScrollView,提供滑动手势以查看更多内容,可以为UITableView集成大量的信息数据。
UITableView仅提供了纵向展示的效果。
UITableViewController类继承自UIViewController类,其中集成了一个UITableView表视图,并且提供了大量的与表视图相关联的方法。
- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style;
style:设置表视图风格
dataSource:设置数据源
delegate:设置委托
rowHeight:设置行高
sectionHeaderHeight:设置头部视图高度
sectionFooterHeight:设置尾部视图高度
backgroundView:背景视图
editing:设置编辑状态
tableHeaderView:设置表头视图
tableFooterView:设置表尾视图
separatorStyle:设置分割线显示风格
separatorColor:设置分割线颜色
bounces:设置是否回弹
sectionIndexBackgroundColor:设置侧边索引栏颜色
sectionIndexColor:设置侧边索引栏标题颜色
sectionIndexTrackingBackgroundColor:设置侧边栏索引视图在拖动时的背景颜色
allowsSelection:设置是否允许选中
allowsSelectionDuringEditing:设置是否允许在编辑状态下选中
allowsMultipleSelection:设置是否允许多选
allowsMultipleSelectionDuringEditing:设置是否允在编辑状态下多选
indexPathForSelectedRow:获取当前选中行的indexPath
indexPathsForSelectedRows:获取当前选中行的所有indexPah
// 1、刷新表视图,重新请求数据源
- (void)reloadData;
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
// 2、获取组所在的区域(包括头部视图、所有单元格以及尾部视图)
- (CGRect)rectForSection:(NSInteger)section;
// 3、获取头部视图、单元格以及尾部视图所在区域
- (CGRect)rectForHeaderInSection:(NSInteger)section;
- (CGRect)rectForFooterInSection:(NSInteger)section;
- (CGRect)rectForRowAtIndexPath:(NSIndexPath *)indexPath;
// 4、获取某个点所在的indexPath
- (nullable NSIndexPath *)indexPathForRowAtPoint:(CGPoint)point;
// 5、获取某一行所在的indexPath
- (nullable NSIndexPath *)indexPathForCell:(UITableViewCell *)cell;
// 6、获取某个区域所在的indexPath集合
- (nullable NSArray<NSIndexPath *> *)indexPathsForRowsInRect:(CGRect)rect;
UITableViewDatasource是一个协议,表视图的datasource对象需要遵守该协议。
通过datasource对象表视图可以获取需要显示数据的所有信息。
UITableViewDataSource 协议方法
// 1、设置组数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
// 2、设置行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
// 3、设置单元格
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
// 4、设置头部标题
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
// 5、设置尾部标题
- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
// 6、设置是否允许编辑单元格
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath;
// 7、设置是否允许移动单元格
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
// 8、设置侧边索引标题
- (nullable NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView;
// 9、提交单元格
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
// 10、移动单元格
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
UITableViewCell单元行是表视图的基本组成元素,用于显示每一行的内容。
多个UITableViewCell单元行构成了一个区段section,表视图中有至少有一个区段。
一个section区段中可以没有cell单元行,也可以有多个cell单元行。
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
UITableViewCellStyleDefault
UITableViewCellStyleValue1
UITableViewCellStyleValue2
UITableViewCellStyleSubtitle
imageView:设置图片显示
textLabel:设置标题文字
detailTextLabel:设置子标题文字
contentView:自定义控件的父视图
backgroundView:设置背景视图
selectedBackgroundView:设置选中时的背景视图
selectionStyle:设置选中展示风格
accessoryType:设置附件指示类型
accessoryView:设置附件视图
editingAccessoryType: 设置编辑状态下的附件指示类型
editingAccessoryView: 设置编辑状态下的附件视图
separatorInset:设置分割线缩进量
UITableViewDelegate是一个协议,表视图的delegate对象需要遵守该协议。
通过delegate对象,可以监控表视图大量的状态事件,并作相应处理,或者可以灵活定制表视图的更多信息。
UITableViewDelegate 协议方法
// 1、设置头部、单元格及尾部视图高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;
// 2、自定义头部及尾部视图
- (nullable UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (nullable UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section;
// 3、设置辅助视图风格
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath;
// 4、选中与取消选中触发方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
// 5、编辑
// 5.1 设置编辑样式
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
// 5.2 设置删除样式标题
- (nullable NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath;
#import
@interface ViewController : UIViewController
@end
#import "ViewController.h"
#import "DetailViewController.h"
static NSString *const kViewControllerTitle = @"Fonts";
static NSString *const kReusableCellIdentifier = @"identifier";
@interface ViewController () <UITableViewDelegate, UITableViewDataSource>
{
NSArray *_sortedKeys; /**< 键 */
NSMutableDictionary *_dataSource; /**< 数据源 */
}
@property (nonatomic, copy) UITableView *tableView; /**< 表格视图 */
- (void)initializeDataSource; /**< 初始化数据源 */
- (void)initializeUserInterface; /**< 初始化用户界面 */
@end
@implementation ViewController
- (void)dealloc
{
NSLog(@"%@", NSStringFromSelector(_cmd));
[_tableView release]; _tableView = nil;
[_dataSource release]; _dataSource = nil;
[_sortedKeys release]; _sortedKeys = nil;
[super dealloc];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self initializeDataSource];
[self initializeUserInterface];
}
#pragma mark *** Initialize methods ***
- (void)initializeDataSource {
// 处理字体数据
_dataSource = [[NSMutableDictionary alloc] init];
NSArray *fonts = [[UIFont familyNames] mutableCopy];
for (NSString *font in fonts) {
NSString *ch = [font substringToIndex:1];
NSMutableArray *font_group = [NSMutableArray arrayWithArray:_dataSource[ch]];
[font_group addObject:font];
[_dataSource setObject:font_group forKey:ch];
}
[fonts release];
// 获取字典key数据
_sortedKeys = [[NSArray alloc] initWithArray:[_dataSource.allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]];
}
- (void)initializeUserInterface {
self.title = kViewControllerTitle;
self.view.backgroundColor = [UIColor whiteColor];
// 关闭系统自动偏移
self.automaticallyAdjustsScrollViewInsets = NO;
// 加载表格视图
[self.view addSubview:self.tableView];
// 自定义返回按钮
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
}
#pragma mark *** UITableViewDataSource ***
// 设置组数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return _sortedKeys.count;
}
// 设置行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return ((NSArray *)_dataSource[_sortedKeys[section]]).count;
}
// 定制单元格
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// 单元格重用机制
// 首先在表格视图中根据标识符寻找可重用的单元格
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kReusableCellIdentifier];
// 判断是否找到可重用的单元格
if (!cell) {
// 如果没有找到则新建单元格
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kReusableCellIdentifier] autorelease];
}
// 设置图片
cell.imageView.image = [UIImage imageNamed:@"log.png"];
// 设置文本信息
NSString *fontName = ((NSArray *) _dataSource[_sortedKeys[indexPath.section]])[indexPath.row];
cell.textLabel.text = fontName;
cell.textLabel.font = [UIFont fontWithName:fontName size:20];
// 设置详情文本信息
cell.detailTextLabel.text = @"Click to enter details.";
// 设置Cell选中风格
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// 设置辅助视图
/**
UITableViewCellAccessoryNone, // don't show any accessory view
UITableViewCellAccessoryDisclosureIndicator, // 向右剪头
UITableViewCellAccessoryDetailDisclosureButton, // info button w/ chevron. tracks
UITableViewCellAccessoryCheckmark, // 钩钩符号
UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0) // 圆圈中间有一个感叹号
*/
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
// 设置行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60;
}
// 这是头部高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 40;
}
// 设置尾部高度
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0;
}
// 设置组标题
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return _sortedKeys[section];
}
// 自定义头部视图
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return nil;
}
// 自定义尾部视图
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return nil;
}
// 设置侧栏索引
- (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return _sortedKeys;
}
#pragma mark *** UITableViewDelegate ***
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *detailVc = [[DetailViewController alloc] init];
detailVc.context = ((NSArray *)_dataSource[_sortedKeys[indexPath.section]])[indexPath.row];
[self.navigationController pushViewController:detailVc animated:YES];
// 设置选中时单元格背景颜色
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.backgroundColor = [UIColor cyanColor];
[detailVc release];
}
// 取消选中
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
// 设置取消选中时单元格背景颜色
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
}
#pragma mark *** Getters ***
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds) - 64) style:UITableViewStylePlain];
// 设置背景颜色
_tableView.backgroundColor = [UIColor clearColor];
// 设置代理
_tableView.delegate = self;
// 设置数据源
_tableView.dataSource = self;
// 设置分割线样式
// 由于iPhone6S plus的分辨率较高,开发的时候通常都使用command + 3 或者 command + 4 缩小模拟器显示,这个时候就相当于把plus的分辨率压缩了所以我们会看不到分割线,解决办法就是把模拟器放大就可以了,选中模拟器按command + 1把模拟器放大就可以了。
_tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
// 设置能否回弹
_tableView.bounces = NO;
// 设置侧栏索引背景色
_tableView.sectionIndexBackgroundColor = [UIColor clearColor];
// 设置侧栏标题色
_tableView.sectionIndexColor = [UIColor blueColor];
// 设置侧栏拖动时的背景颜色
_tableView.sectionIndexTrackingBackgroundColor = [UIColor lightGrayColor];
}
return _tableView;
}
@end
#import
@interface DetailViewController : UIViewController
@property (nonatomic, copy)NSString *context;
@end
#import "DetailViewController.h"
@interface DetailViewController ()
@property (nonatomic, copy)UILabel *contextLabel;
- (void)initializeUserInterface; /**< 初始化用户界面 */
@end
@implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initializeUserInterface];
}
#pragma mark *** Initialize methods ***
- (void)dealloc
{
[_context release]; _context = nil;
[super dealloc];
}
- (void)initializeUserInterface {
self.title = @"Details";
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.contextLabel];
}
#pragma mark *** Getters ***
- (UILabel *)contextLabel {
if (!_contextLabel) {
_contextLabel = [[UILabel alloc] init];
_contextLabel.bounds = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 30);
_contextLabel.center = self.view.center;
_contextLabel.textAlignment = NSTextAlignmentCenter;
_contextLabel.text = self.context;
_contextLabel.font = [UIFont fontWithName:self.context size:25];
}
return _contextLabel;
}
@end