开头
UITableViewController
实际用处
- 微博推文界面
- 微信、QQ的好友界面,聊天界面
- 新闻界面
- 只要是界面上需要列举内容,而且每块内容需要的数据,都大致相同,就可以用到
基础用法
UITableViewController
数据的加载也是通过UITableViewDataSource
的代理方法实现的
- 头尾也可以返回
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.textLabel.text = @"test";
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [NSString stringWithFormat:@"Header%ld", section];
}
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
return [NSString stringWithFormat:@"Footer%ld", section];
}
UITableView
表单样式
UITableViewStylePlain
UITableViewStyleGrouped
UITableViewStyleInsetGrouped
- 设置
UITableViewController
的表单样式
- (instancetype)initWithStyle:(UITableViewStyle)style {
return [super initWithStyle:UITableViewStyleInsetGrouped];
}
self.view = [[UITableView alloc] initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStyleGrouped];
一些设置
UITableViewCellSeparatorStyleNone,
UITableViewCellSeparatorStyleSingleLine,
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
self.tableView.separatorColor = [UIColor redColor]
self.tableView.tintColor = [UIColor orangeColor]
数据刷新
//刷新全部
[self.tableView reloadData]
//刷新某一组
NSIndexSet *idxSet = [NSIndexSet indexSetWithIndex:1]
[self.tableView reloadSections:idxSet withRowAnimation:UITableViewRowAnimationFade]
//刷新某一行
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:2 inSection:1]
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]
UITableViewCell
- 在实际开发中,
UITableViewCell
一般是自定义的,但是要求不高的时候也会选择用系统的cell
类型
UITableViewCellStyleDefault
UITableViewCellStyleValue1
UITableViewCellStyleValue2
UITableViewCellStyleSubtitle
基本设置
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil]
cell.textLabel.text = @"test"
cell.imageView.image = [UIImage imageNamed:@"dv_icon1"]
cell.detailTextLabel.text = @"detail"
一些设置
cell.accessoryType = UITableViewCellAccessoryDetailButton;
UITableViewCellAccessoryNone
UITableViewCellAccessoryDisclosureIndicator
UITableViewCellAccessoryDetailDisclosureButton
UITableViewCellAccessoryCheckmark
UITableViewCellAccessoryDetailButton
- 选中形式,blue和gray设置后的样式和default一样,不知道什么原因
UITableViewCellSelectionStyleNone,
UITableViewCellSelectionStyleBlue,
UITableViewCellSelectionStyleGray,
UITableViewCellSelectionStyleDefault
cell.selectionStyle = UITableViewCellSelectionStyleNone;
高度
- 实际开发中,每个cell的高度不尽相同,可以在自定义的模型中,计算好高度属性
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
}
应用场景的功能
滚动
- 滚动到指定位置,例如,点击QQ或者微信的输入框,界面自动滚到最后一条消息。滚动有四个位置,但是我尝试了,没有什么区别
[self.tableView scrollToRowAtIndexPath:idxPath
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
UIRefreshControl实现下拉刷新
- 通过
refreshControl
,是UITableViewController
自带的刷新控件
- 只要设置了
refreshControl
,该控件就一直存在
//创建,在viewDidLoad中创建
UIRefreshControl *rc = [UIRefreshControl new]
//指定方法
[rc addTarget:self action:@selector(loadData) forControlEvents:UIControlEventValueChanged]
//菊花颜色
rc.tintColor = [UIColor orangeColor]
//自定义文字
NSDictionary *attrDic = @{
NSFontAttributeName : [UIFont systemFontOfSize:20],
NSForegroundColorAttributeName : [UIColor redColor],
NSBackgroundColorAttributeName : [UIColor blueColor]
}
rc.attributedTitle = [[NSAttributedString alloc] initWithString:@"正在刷新" attributes:attrDic]
self.refreshControl = rc
//开始,在自定义中,可以重写,进行自定义刷新动画的设置,就需要手动调用
[self.refreshControl beginRefreshing]
//结束
[self.refreshControl endRefreshing]
- 由于
UIRefreshControl
在刷新时不会自动调用beginRefreshing
,所以要手动调用,并且通过重写beginRefreshing
和endRefreshing
,实现自定义动画效果,把原来的菊花掩盖
- 自定义
UIRefreshControl
,下面这个例子,简单的用UIView
显示了动画变化,并用KVO
的方法调用beginRefreshing
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if (self.isRefreshing) {
[UIView animateWithDuration:1 animations:^{
self.v1.alpha = 0.5;
self.v2.alpha = 1;
}]
}
}
//初始化函数
- (instancetype)init
{
self = [super init]
if (self) {
[self setupUI]
//kvo检测是否拖动
[self addObserver:self forKeyPath:@"frame" options:0 context:nil]
}
return self
}
- (void)dealloc
{
//移除kvo
[self removeObserver:self forKeyPath:@"frame"]
}
- (void)beginRefreshing {
[super beginRefreshing]
NSLog(@"CustomRefreshControl - beginRefreshing")
[UIView animateWithDuration:1 animations:^{
self.v1.alpha = 0.5;
self.v2.alpha = 1;
}]
}
- (void)endRefreshing {
[super endRefreshing]
NSLog(@"CustomRefreshControl - endRefreshing")
[UIView animateWithDuration:1 animations:^{
self.v1.alpha = 1;
self.v2.alpha = 0;
}]
}
- (void)setupUI {
UIView *v1 = [UIView new]
v1.frame = CGRectMake(50, 0, self.bounds.size.width, self.bounds.size.height)
v1.backgroundColor = [UIColor redColor]
UIView *v2 = [UIView new]
v2.frame = CGRectMake(50, 0, self.bounds.size.width, self.bounds.size.height)
v2.backgroundColor = [UIColor blueColor]
v2.alpha = 0
self.tintColor = [UIColor clearColor]
[self addSubview:v2]
[self addSubview:v1]
self.v1 = v1
self.v2 = v2
}
通过headerView实现下拉刷新
- 但是,用
UIRefreshControl
,会有一个问题,在实际刷新的时候,刷新的图层会出现在UITableView
的上方不是很美观,所以对于不需要headerView
的表单中,我选择通过自定义UIView
借用headerView
来实现下拉刷新
RefreshView
与自定义UIRefreshControl
类似,在beginRefreshing
和endRefreshing
中写出对应的动画,在应该待调用的时候调用,这里就不再重复写了
- viewDidLoad的基础设置
self.refreshView = [[RefreshView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)]
//获取状态栏高度
CGFloat statusHeight = [UIApplication sharedApplication].windows.firstObject.windowScene.statusBarManager.statusBarFrame.size.height
//设置tableView的向上偏移量
self.tableView.contentInset = UIEdgeInsetsMake(-50-statusHeight, 0, 0, 0)
self.tableView.tableHeaderView = self.refreshView
self.refreshFlag = NO
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
NSLog(@"%f", scrollView.contentOffset.y);
if (velocity.y < 0 && self.tableView.contentOffset.y < -self.tableView.tableHeaderView.bounds.size.height) {
[self.refreshView beginRefreshing];
self.refreshFlag = YES;
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
CGFloat statusHeight = [UIApplication sharedApplication].windows.firstObject.windowScene.statusBarManager.statusBarFrame.size.height
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if(self.refreshFlag) {
[UIView animateWithDuration:0.5 animations:^{
//数据获取结束,调用结束刷新,并且还原界面位置
[self.refreshView endRefreshing]
self.refreshFlag = NO
self.tableView.contentInset = UIEdgeInsetsMake(-50-statusHeight, 0, 0, 0)
}]
}
})
}
上拉刷新
- 上拉刷新
- 往往上拉刷新是不用特别花哨的,用系统自带的即可
//设置上拉刷新视图
self.footerView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleMedium]
self.tableView.tableFooterView = self.footerView
//开始刷新
[self.footerView startAnimating]
//结束刷新
[self.footerView stopAnimating]
跳转或者执行方法
- 选中某一行的处理,例如跳转到不同的界面,下面是,根据文本,跳转到界面,将
NSString
转换成类
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]
NSString *targetVC = cell.textLabel.text
Class class = NSClassFromString(targetVC)
UIViewController *vc = [class new]
[self presentViewController:vc animated:YES completion:nil]
}
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]
NSString *targetFunc = cell.textLabel.text
SEL funcName = NSSelectorFromString(targetFunc)
[self performSelector:funcName]
[self performSelector:funcName withObject:@"name" withObject:@18];
- (void)testViewController:(NSString *)name andAge:(NSNumber *)age {
NSLog(@"testViewController %@ %d", name, [age intValue]);
}
cell.textLabel.text = @"testViewController:andAge:";