iOS UI基础-9.0 UITableView基础
在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView。UITableView继承自UIScrollView,因此支持垂直滚动,而且性能极佳。
UITableView有两种样式:
- 一列显示:UITableViewStylePlain
- 分组显示:UITableViewStyleGrouped
tableView展示数据的过程
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
2.调用数据源的下面方法得知每一组有多少行数据
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
3.调用数据源的下面方法得知每一行显示什么内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
常见的属性
// 表格行线条的颜色
self.tableView.separatorColor = [UIColor colorWithRed:/255.0 green:/255.0 blue: alpha:/255.0];
// 显示表格行线条的样式,UITableViewCellSeparatorStyleNone为没有线条
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; // 表格的头部控件(直接显示表格的最顶部),一般用来显示广告
self.tableView.tableHeaderView = [UIButton buttonWithType:UIButtonTypeContactAdd];
// 表格的底部控件,一般用来加载更多数据
self.tableView.tableFooterView = [[UISwitch alloc] init];
// 行选中为透明
cell.selectionStyle=UITableViewCellSeparatorStyleNone;
Cell的重用代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.定义一个cell的标识。static修饰局部变量:可以保证局部变量只分配一次存储空间(只初始化一次)
static NSString *ID = @"mjcell"; // 2.从缓存池中取出cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // 3.如果缓存池中没有cell
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
} // 4.设置cell的属性...
return cell;
}
右边索引条
已经有相应的数据源,实现即可
/**
* 返回右边索引条显示的字符串数据
*/
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
return [self.groups valueForKeyPath:@"title"];
}
效果:
刷新表格
// 全局刷新(每一行都会重新刷新)
- (void)reloadData; // 局部刷新(使用前提: 刷新前后, 模型数据的个数不变)
- (void)reloadRows:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation; // 局部删除(使用前提: 模型数据减少的个数 == indexPaths的长度)
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
实例:
// 全部刷新
[self.tableView reloadData]; // 局部刷新,row指的是第几行,inSection指的是第几组
NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:];
[self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationBottom];
滑动删除与新增
只需要实现tableview代理即可
/**
* 当tableView进入编辑状态的时候会调用,询问每一行进行怎样的操作(添加\删除)
*/
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
//return indexPath.row %2 ? UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleInsert;
}
如果显示的是英文Delete,可以通过设置模拟器的语言,同时增加中文语言
选中InfoPlist.strings和InfoPlist.strings
监听点击滑动删除按钮
/**
* 如果实现了这个方法,就自动实现了滑动删除的功能
* 点击了删除按钮就会调用
* 提交了一个编辑操作就会调用(操作:删除\添加)
* @param editingStyle 编辑的行为
* @param indexPath 操作的行号
*/
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) { // 提交的是删除操作
// 1.删除模型数据
[self.contacts removeObjectAtIndex:indexPath.row]; // 2.刷新表格
// 局部刷新某些行(使用前提:模型数据的行数不变)
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop]; // 3.归档
[NSKeyedArchiver archiveRootObject:self.contacts toFile:MJContactsFilepath];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// 1.修改模型数据
MJContact *contact = [[MJContact alloc] init];
contact.name = @"jack";
contact.phone = @"";
[self.contacts insertObject:contact atIndex:indexPath.row + ]; // 2.刷新表格,使用局部刷新
NSIndexPath *nextPath = [NSIndexPath indexPathForRow:indexPath.row + inSection:];
[self.tableView insertRowsAtIndexPaths:@[nextPath] withRowAnimation:UITableViewRowAnimationBottom];
// [self.tableView reloadData];
}
}
其它属性
// 2.设置每一组头部尾部的高度
self.tableView.sectionFooterHeight = 0;
self.tableView.sectionHeaderHeight = 10;
// 3.设置背景色
self.tableView.backgroundView = nil;
self.tableView.backgroundColor = IWGlobalBgColor;
常用实例:
#pragma mark - 初始化界面 - (void)setupTableView
{
_tableView= [[UITableView alloc] initWithFrame:CGRectMake(, , kScreenWidth, kScreenHeight) style:UITableViewStyleGrouped];;
_tableView.dataSource = self;
_tableView.delegate=self;
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.tableHeaderView = [self tableHeaderView];
_tableView.tableFooterView = [UIView new];
[self.view addSubview:_tableView];
} // 初始化头部
- (UIView *)tableHeaderView
{ } #pragma mark - UITableViewDataSource数据源方法
// 返回分组数
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
NSLog(@"计算分组数");
return ;
} // 返回每组行数
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(@"计算每组(组%i)行数",section);
return group1.contacts.count;
} // 返回每行的单元格
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *ID = @"RFMeTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
cell.textLabel.text = @"文字";
cell.imageView.image = [UIImage imageNamed:@"me_phone_icon"];
return cell;
} // 返回每组头标题名称
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
NSLog(@"生成组(组%i)名称",section);
return group.name;
} // 返回每组尾部说明
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
NSLog(@"生成尾部(组%i)详情",section);
return group.detail;
} #pragma mark - UITableViewDelegate 代理方法
// 设置分组标题内容高度
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
if(section==){
return ;
}
return ;
} // 设置每行高度(每行高度可以不一样)
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return ;
} // 设置尾部说明内容高度
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return ;
} // 点击行
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ }
点击效果
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
//当手指离开某行时,就让某行的选中状态消失
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
TableView样式
如果带有图标,我们使用系统自带的tableviewCell.ImageView.image来设置的话,会发现,底下的这条线没有包括图标,类型QQ的效果,如:
现在有一个需求,是改成类型微信的显示效果,底部是线包括图标,如:
我们会发现,当tableviewcell.imageView.image 为空的时候,横线是到图标的这个位置的。因而,简单的做法是,不使用系统的,自定义一个imageview,并设置tableviewcell.textLabel的X值。
// 1.设置基本数据
if (item.icon) {
_iconImage.image = [UIImage imageNamed:item.icon];
} else {
_iconImage.frame = CGRectZero;
}
//self.imageView.image = [UIImage imageNamed:item.icon];
self.textLabel.text = item.title;
self.detailTextLabel.text = item.subtitle;
改为textLable的X值
- (void)layoutSubviews
{
[super layoutSubviews]; // 调整子标题的x
self.detailTextLabel.x = CGRectGetMaxX(self.textLabel.frame) + ; if (_item.icon) {
self.textLabel.x = ;
}
}
参考完成代码:
//
// MeCommonCell.m
// 99SVR
//
// Created by jiangys on 16/6/2.
// Copyright © 2016年 xia zhonglin . All rights reserved.
// #import "MeCommonCell.h"
#import "CommonCellLabelItem.h"
#import "CommonCellArrowItem.h" @interface MeCommonCell()
/** 箭头 */
@property (nonatomic, strong) UIImageView *rightArrow;
/** 标签 */
@property (nonatomic, strong) UILabel *rightLabel;
/** 图标 这里不使用自带的self.imageView.image,因为底部横线不会包括自带的图标*/
@property(nonatomic, strong) UIImageView *iconImage;
@end @implementation MeCommonCell #pragma mark - 懒加载右边的view
- (UIImageView *)rightArrow
{
if (_rightArrow == nil) {
UIImageView *arrowImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow"]];
arrowImageView.size = (CGSize){,};
self.rightArrow = arrowImageView;
}
return _rightArrow;
} - (UILabel *)rightLabel
{
if (_rightLabel == nil) {
self.rightLabel = [[UILabel alloc] init];
self.rightLabel.textColor = COLOR_Text_Gay;
self.rightLabel.font = Font_14;
}
return _rightLabel;
} #pragma mark - 初始化
+ (instancetype)cellWithTableView:(UITableView *)tableView
{
static NSString *ID = @"MeCommonCell";
MeCommonCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[MeCommonCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID];
}
return cell;
} - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_iconImage = [[UIImageView alloc] initWithFrame:CGRectMake(,, , self.height)];
_iconImage.contentMode = UIViewContentModeScaleAspectFit;
[self.contentView addSubview:_iconImage]; // 设置标题的字体
self.textLabel.font = Font_15;
self.textLabel.textColor = COLOR_Text_Black;
self.detailTextLabel.font = Font_14; // 设置cell的默认背景色
self.backgroundColor = [UIColor whiteColor];
}
return self;
} #pragma mark - 调整子控件的位置
- (void)layoutSubviews
{
[super layoutSubviews]; // 调整子标题的x
self.detailTextLabel.x = CGRectGetMaxX(self.textLabel.frame) + ; if (_item.icon) {
self.textLabel.x = ;
}
} - (void)setItem:(CommonCellItem *)item
{
_item = item; // 1.设置基本数据
if (item.icon) {
_iconImage.image = [UIImage imageNamed:item.icon];
} else {
_iconImage.frame = CGRectZero;
}
//self.imageView.image = [UIImage imageNamed:item.icon];
self.textLabel.text = item.title;
self.detailTextLabel.text = item.subtitle; // 2.设置右边的内容
if ([item isKindOfClass:[CommonCellArrowItem class]]) {
self.accessoryView = self.rightArrow;
} else if ([item isKindOfClass:[CommonCellLabelItem class]]) {
CommonCellLabelItem *labelItem = (CommonCellLabelItem *)item;
// 设置文字
self.rightLabel.text = labelItem.text;
// 根据文字计算尺寸
self.rightLabel.size = [labelItem.text sizeMakeWithFont:self.rightLabel.font];
self.accessoryView = self.rightLabel;
} else { // 取消右边的内容
self.accessoryView = nil;
}
}
@end
网摘一些小总结:
//这句话不显示多余的单元格
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; // 这句话不显示单元格之间的分割线
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // 这句话在单元格的最后显示一个箭头
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; //--- 点击cell的时候 cell不会产生高亮状态 ---
cell.selectionStyle = UITableViewCellSelectionStyleNone; // --- 写在viewdidload里面cell自适应高度 ----
tableView.rowHeight = UITableViewAutomaticDimension; // 自适应单元格高度
tableView.estimatedRowHeight = ; //先估计一个高度 // 去掉UItableview headerview黏性(sticky)
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat sectionHeaderHeight = ;
if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, , , );
}
else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, , , );
}
} // 获取手势点击的是哪一个cell的坐标
NSIndexPath *indexPath = [self.tableView indexPathForCell:((UITableViewCell *)longPress.view)]; // 局部刷新
//一个section刷新
NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:];
[tableview reloadSections:indexSet withRowAnimation:UITableViewRowAnimationAutomatic]; //一个cell刷新
NSIndexPath *indexPath=[NSIndexPath indexPathForRow: inSection:];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone]; // 关于UITableView如何跳转到最后一行或者任意指定行。
其实现如下:
[self.chatTableView scrollToRowAtIndexPath:
[NSIndexPath indexPathForRow:[self.chatArray count]- inSection:]
atScrollPosition: UITableViewScrollPositionBottom
animated:NO]; // 点击button时获取button所在的cell的indexpath
UIButton *button = sender;
HeroDermaTableViewCell *cell = (HeroDermaTableViewCell *)[[button superview] superview];
NSIndexPath *indexPath = [_tableView indexPathForCell:cell];
分组状态下,顶部留白,解决办法
table.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, CGFLOAT_MIN)];
iOS UI基础-9.0 UITableView基础的更多相关文章
- iOS UI进阶-1.0 Quartz2D
概述 Quartz 2D是一个二维绘图引擎,同时支持iOS和Mac系统.Quartz 2D能完成的工作: 绘制图形 : 线条\三角形\矩形\圆\弧等 绘制文字 绘制\生成图片(图像) 读取\生成PDF ...
- [iOS UI进阶 - 6.0] CALayer
A.基本知识 1.需要掌握的 CALayer的基本属性 CALayer和UIView的关系 position和anchorPoint的作用 2.概念 在iOS中,你能看得见摸得着的东西基本上都是U ...
- [iOS UI进阶 - 5.0] 手势解锁Demo
A.需求 1.九宫格手势解锁 2.使用了绘图和手势事件 code source: https://github.com/hellovoidworld/GestureUnlockDemo B ...
- [iOS UI进阶 - 3.0] 触摸事件的基本处理
A.需要掌握和练习的 1.介绍事件类型2.通过按钮的事件处理引出view的事件处理3.响应者对象 --> UIResponder --> UIView4.view的拖拽* 实现触摸方法,打 ...
- [iOS UI进阶 - 2.0] 彩票Demo v1.0
A.需求 1.模仿“网易彩票”做出有5个导航页面和相应功能的Demo 2.v1.0 版本搭建基本框架 code source:https://github.com/hellovoidworld/H ...
- IOS UI 第十一篇: UITABLEVIEW
DIY a tableviewcell : - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *) ...
- IOS UI 第十篇: UITABLEVIEW
uitableView review yesterday’s knowledge : folding group : ------------------------------- ...
- iOS UI进阶-4.0 地图与定位
在移动互联网时代,移动app能解决用户的很多生活琐事,比如 导航:去任意陌生的地方 周边:找餐馆.找酒店.找银行.找电影院 在上述应用中,都用到了地图和定位功能,在iOS开发中,要想加入这2大功能 ...
- [iOS UI进阶 - 4.0] 涂鸦app Demo
A.需求 1.超简易画图,只有一种画笔 2.清屏功能 3.回退功能 4.保存功能 5.使用了cocos2D code source: https://github.com/hellovoidwor ...
随机推荐
- Linux之文档与目录结构 目录的相关操作 Linux的文件系统
Linux之文档与目录结构 Linux文件系统结构 Linux目录结构的组织形式和Windows有很大的不同.首先Linux没有“盘(C盘.D盘.E盘)”的概念.已经建立文件系统的硬盘分区被挂载到 ...
- Global Error Handling in ASP.NET Web API 2(webapi2 中的全局异常处理)
目前,在Web API中没有简单的方法来记录或处理全局异常(webapi1中).一些未处理的异常可以通过exception filters进行处理,但是有许多情况exception filters无法 ...
- js return false\e.preventDefault() 以及session
@{ ViewBag.Title = "Test"; } <h2>Test</h2> 区别的介绍 <br/> 我们在平时的编码中javascri ...
- [linux] 对一个虚拟机的研究
今天拿到了一个vmware的虚拟机硬盘镜像,是其他公司的演示产品. 启动之后是带着ubuntu字样的grub.进入系统之后也不是shell,而是一个定制的命令行.所以如果想了解细节的话,只能单独挂硬盘 ...
- 转:HashMap实现原理分析(面试问题:两个hashcode相同 的对象怎么存入hashmap的)
原文地址:https://www.cnblogs.com/faunjoe88/p/7992319.html 主要内容: 1)put 疑问:如果两个key通过hash%Entry[].length得 ...
- day3_字符串常用方法
s.upper()s.lower()s.capitalize()s.split(',')s.strip('abc')s.lstrip()s.rstrip()s.replace('old','new') ...
- centos中文语言安装
1.查看当前使用的系统语言 #echo LANG 2.查看系统是否安装中文 #locale 如有zh_cn,表示已经安装了中文语言 3.安装中文 #yum groupinstall chinese-s ...
- 使用IntelliJ IDEA创建Maven聚合工程、创建resources文件夹、ssm框架整合、项目运行一体化
一.创建一个空的项目作为存放整个项目的路径 1.选择 File——>new——>Project ——>Empty Project 2.WorkspaceforTest为项目存放文件夹 ...
- MongoDB update修改器 目录
MongoDB update修改器: 针对Fields的$修改器 $inc $set $unset MongoDB update修改器: 针对Arrays的$修改器 $push $pull $pop ...
- 关于ios下字体描边的一个细节
转载请注明,来自:http://blog.csdn.net/skyman_2001 CGContextSetTextDrawingMode(context, kCGTextStroke); ...