iOS App开发中使用及自定义UITableViewCell的教程

UITableView用来以表格的形式显示数据。关于UITableView,我们应该注意:

(1)UITableView用来显示表格的可见部分,UITableViewCell用来显示表格的一行。

(2)UITableView并不负责存储表格中的数据,而是仅仅存储足够的数据使得可以画出当前可见部分。

(3)UITableView从UITableViewDelegate协议获取配置信息,从UITableViewDataSource协议获得数据信息。

(4)所有的UITableView实现时实际上只有一列,但是我们可以通过向UITableViewCell中添加子视图,使得它看起来有好几列。

(5)UITableView有两种风格:

① Grouped:每一组看起来像是圆矩形;
    ② Plain:这是默认风格,可以修改成Indexed风格。
   
UITableViewCell使用实例
在下边的小例子中,我们将先实现显示一列数据,然后在每行添加图像,之后再看看UITableViewCell的四种分别是什么样的。最后再进行其他操作,比如设置缩进、修改字体大小和行高等。

1、运行Xcode 4.2,新建一个Single View Application,名称为Table Sample:

2、单击ViewController.xib,使用Interface Builder给视图添加一个UITableView控件,并使其覆盖整个视图:

3、选中新添加的UITableView控件,打开Connection Inspector,找到delegate和datasource,从它们右边的圆圈拉线到File's Owner图标:

4、单击ViewController.h,在其中添加代码:

代码如下:

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
@property (strong, nonatomic) NSArray *listData;
@end

5、单击ViewController.m,在其中添加代码:

5.1 在@implementation后面添加代码:

代码如下:

@synthesize listData;

5.2 在viewDidLoad方法中添加代码:

代码如下:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSArray *array = [[NSArray alloc] initWithObjects:@"Tree", @"Flower",
                      @"Grass", @"Fence", @"House", @"Table", @"Chair",
                      @"Book", @"Swing" , nil];
    self.listData = array;
}

5.3 在viewDidUnload方法中添加代码:

代码如下:

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.listData = nil;
}

5.4 在@end之前添加代码:

代码如下:

#pragma mark -
#pragma mark Table View Data Source Methods
//返回行数
- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section {
    return [self.listData count];
}

//新建某一行并返回
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
   
    static NSString *TableSampleIdentifier = @"TableSampleIdentifier";
   
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
                             TableSampleIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]
                initWithStyle:UITableViewCellStyleDefault
                reuseIdentifier:TableSampleIdentifier];
    }
   
    NSUInteger row = [indexPath row];
    cell.textLabel.text = [listData objectAtIndex:row];
 return cell;
}

上面的第二个方法中,

代码如下:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: TableSampleIdentifier];

这个语句根据标识符TableSampleIdentifier寻找当前可以重用的UITableViewCell。当某行滑出当前可见区域后,我们重用它所对应的UITableViewCell对象,那么就可以节省内存和时间。
如果执行词语后,cell为nil,那我们再创建一个,并设置去标识符为TableSampleIdentifier:

代码如下:

cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableSampleIdentifier];

这里UITableViewCellStyleDefault是表示UITableViewCell风格的常数,除此之外,还有其他风格,后面将会用到。
注意参数(NSIndexPath *)indexPath,它将行号row和部分号section合并了,通过[indexPath row];获取行号。之后给cell设置其文本:

代码如下:

cell.textLabel.text = [listData objectAtIndex: row];

6、运行一下:

7、给每一行添加图片:
7.1 将图片资源添加到工程:拖到工程中,前面的文章有提到。
7.2 在cellForRowAtIndexPath方法的return语句之前添加代码:

代码如下:

UIImage *image = [UIImage imageNamed:@"blue.png"];
cell.imageView.image = image;
UIImage *highLighedImage = [UIImage imageNamed:@"yellow.png"];
cell.imageView.highlighedImage = highLighedImage;

7.3 运行,效果如下:

可以看到,每行左边都出现一张图片。当选中某行,其图片改变。

8、设置行的风格:
表示UITableViewCell风格的常量有:

代码如下:

UITableViewCellStyleDefault
UITableViewCellStyleSubtitle
UITableViewCellStyleValue1
UITableViewCellStyleValue2

这几种风格的区别主要体现在Image、Text Label以及Detail Text Label。
为了体现风格,在cellForRowAtIndexPath方法的return语句之前添加代码:

代码如下:

cell.detailTextLabel.text = @"Detail Text";

然后将

代码如下:

cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableSampleIdentifier];

中的UITableViewCellStyleDefault依次换成上面提到的四个风格常量,并运行,效果分别如下:

UITableViewCellStyleDefault

UITableViewCellStyleSubtitle

UITableViewCellStyleValue1

UITableViewCellStyleValue2
    
9、设置缩进:

将所有行的风格改回UITableViewCellStyleDefault,然后在@end之前添加代码如下:

代码如下:

#pragma mark Table Delegate Methods
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger row = [indexPath row];
    return row;
}

这里将第row行缩进row,如下图所示:

10、操纵行选择:
在@end之前添加代码:

代码如下:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger row = [indexPath row];
    if (row%2 == 0) {
        return nil;
    }
    return indexPath;
}

上面的方法在选择某行之前执行,我们可以在这个方法中添加我们想要的操作。这里,我们实现的是,如果选择的行号(从0开始计)是偶数,则取消选择。
在@end之前添加代码:

代码如下:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger row = [indexPath row];
    NSString *rowValue = [listData objectAtIndex:row];
   
    NSString *message = [[NSString alloc] initWithFormat:
                         @"You selected %@", rowValue];
    UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"Row Selected!"
                          message:message
                          delegate:nil
                          cancelButtonTitle:@"Yes I Did"
                          otherButtonTitles:nil];
    [alert show];
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

当选择某行之后,就弹出一个Alert,用来显示我们所做的选择。
运行一下,你会发现第0、2等行无法选择。选择奇数行时会弹出提示:

而且关闭提示框后,选择的那行也被取消了选择,用的语句

代码如下:

[tableView deselectRowAtIndexPath:indexPath animated:YES];

11、设置字体大小和表格行高:
11.1 在cellForRowAtIndexPath方法中的return之前添加代码,用于设置字体和大小:

代码如下:

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

11.2 在@end之前添加代码,用于设置行高:

代码如下:

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

运行,看看效果:

可任意自定义的UITableViewCell
UITableView的强大更多程度上来自于可以任意自定义UITableViewCell单元格。通常,UITableView中的Cell是动态的,在使用过程中,会创建一个Cell池,根据每个cell的高度(即tableView:heightForRowAtIndexPath:返回值),以及屏幕高度计算屏幕中可显示几个cell。而进行自定义TableViewCell无非是采用代码实现或采用IB编辑nib文件来实现两种方式,本文主要收集代码的方式实现各种cell自定义。
1.如何动态调整Cell高度

代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 
    static NSString *CellIdentifier = @"Cell";
 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
        label.tag = 1;
        label.lineBreakMode = UILineBreakModeWordWrap;
        label.highlightedTextColor = [UIColor whiteColor];
        label.numberOfLines = 0;
        label.opaque = NO; // 选中Opaque表示视图后面的任何内容都不应该绘制
        label.backgroundColor = [UIColor clearColor];
        [cell.contentView addSubview:label];
        [label release];
    }
 
    UILabel *label = (UILabel *)[cell viewWithTag:1];
    NSString *text;
    text = [textArray objectAtIndex:indexPath.row];
    CGRect cellFrame = [cell frame];
    cellFrame.origin = CGPointMake(0, 0);
 
    label.text = text;
    CGRect rect = CGRectInset(cellFrame, 2, 2);
    label.frame = rect;
    [label sizeToFit];
    if (label.frame.size.height > 46) {
        cellFrame.size.height = 50 + label.frame.size.height - 46;
    }
    else {
        cellFrame.size.height = 50;
    }
    [cell setFrame:cellFrame];
 
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    return cell.frame.size.height;
}

2.如何用图片自定义Table Separeator分割线
一般地,利用类似[tableView setSeparatorColor:[UIColor redColor]];语句即可修改cell中间分割线的颜色。那又如何用一个图片作为分割线背景呢?可以尝试如下:
方法一:
先设置cell separatorColor为clear,然后把图片做的分割线添加到自定义的custom cell上。

方法二:
在cell里添加一个像素的imageView后将图片载入进,之后设置tableView.separatorStyle = UITableViewCellSeparatorStyleNone

3.自定义首行Cell与其上面导航栏间距

代码如下:

tableView.tableHeaderView = [[[UIView alloc] initWithFrame:CGRectMake(0,0,5,20)] autorelease];

4.自定义UITableViewCell的accessory样式
默认的accessoryType属性有四种取值:UITableViewCellAccessoryNone、UITableViewCellAccessoryDisclosureIndicator、UITableViewCellAccessoryDetailDisclosureButton、UITableViewCellAccessoryCheckmark。如果想使用自定义附件按钮的其他样式,则需使用UITableView的accessoryView属性来指定。

代码如下:

UIButton *button;
if(isEditableOrNot) {
    UIImage *image = [UIImage imageNamed:@"delete.png"];
    button = [UIButton buttonWithType:UIButtonTypeCustom];
    CGRect frame = CGRectMake(0.0,0.0,image.size.width,image.size.height);
    button.frame = frame;
    [button setBackgroundImage:image forState:UIControlStateNormal];
    button.backgroundColor = [UIColor clearColor];
    cell.accessoryView = button;
}else{
    button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.backgroundColor = [UIColor clearColor];
    cell.accessoryView = button;
}

以上代码仅仅是定义了附件按钮两种状态下的样式,问题是现在这个自定义附件按钮的事件仍不可用。即事件还无法传递到UITableViewDelegate的accessoryButtonTappedForRowWithIndexPath方法上。当我们在上述代码中在加入以下语句:

代码如下:

[button addTarget:self action:@selector(btnClicked:event:) forControlEvents:UIControlEventTouchUpInside];

后,虽然可以捕捉到每个附件按钮的点击事件,但我们还无法进行区别到底是哪一行的附件按钮发生了点击动作!因为addTarget:方法最多允许传递两个参数:target和event,这两个参数都有各自的用途了(target指向事件委托对象,event指向所发生的事件)。看来只依靠Cocoa框架已经无法做到了。

但我们还是可以利用event参数,在自定义的btnClicked方法中判断出事件发生在UITableView的哪一个cell上。因为UITableView有一个很关键的方法indexPathForRowAtPoint,可以根据触摸发生的位置,返回触摸发生在哪一个cell的indexPath。而且通过event对象,正好也可以获得每个触摸在视图中的位置。

代码如下:

// 检查用户点击按钮时的位置,并转发事件到对应的accessory tapped事件
- (void)btnClicked:(id)sender event:(id)event
{
     NSSet *touches = [event allTouches];
     UITouch *touch = [touches anyObject];
     CGPoint currentTouchPosition = [touch locationInView:self.tableView];
     NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:currentTouchPosition];
     if(indexPath != nil)
     {
         [self tableView:self.tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
     }
}

这样,UITableView的accessoryButtonTappedForRowWithIndexPath方法会被触发,并且获得一个indexPath参数。通过这个indexPath参数,我们即可区分到底哪一行的附件按钮发生了触摸事件。

代码如下:

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
    int  *idx = indexPath.row;
   //这里加入自己的逻辑
}

(0)

相关推荐

  • 全面解析iOS应用中自定义UITableViewCell的方法

    有时候我们需要自己定义UITableViewCell的风格,其实就是向行中添加子视图.添加子视图的方法主要有两种:使用代码以及从.xib文件加载.当然后一种方法比较直观. 一.基本用法 我们这次要自定义一个Cell,使得它像QQ好友列表的一行一样:左边是一张图片,图片的右边是三行标签: 当然,我们不会搞得这么复杂,只是有点意思就行. 1.运行Xcode 4.2,新建一个Single View Application,名称为Custom Cell: 2.将图片资源导入到工程.为此,我找了14张50

  • 详解ios中自定义cell,自定义UITableViewCell

    通过继承UITableViewCell来自定义cell 1.创建一个空的项目.命名: 2.创建一个UITableViewController 并且同时创建xib: 3.设置AppDelegate.m中window的根控制器为刚刚创建的TableViewController: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { s

  • 详解IOS UITableViewCell 的 imageView大小更改

    详解IOS UITableViewCell 的 imageView大小更改 实例代码: - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCell

  • IOS UITableViewCell详解及按钮点击事件处理实例

    IOS UITableViewCell详解及按钮点击事件处理 今天突然做项目的时候,又遇到处理自定义的UITableViewCell上按钮的点击事件问题.我知道有两种方式,可是突然想不起来之前是怎么做的了,好记性不如烂笔头,还是记录一下吧. 1.第一种方式给Button加上tag值 这里分为两种:一种是直接在原生的UITableViewCell上添加UIButton按钮,然后给UIButton设置tag值,然后在控制器里的方法里通过取数据,做界面跳转等.还是举个例子吧,省的回忆半天. - (UI

  • IOS UITableView和UITableViewCell的几种样式详细介绍

    IOS UITableView和UITableViewCell的几种样式详细介绍 今天要分享的是IOS开发中一个使用率非常高的一个控件-------UITableView,这两天正在使用tableview做信息的显示,在写代码时对tableview和tableviewcell的几种样式一直分不清楚,今天我详细的研究了一下,下面就跟大家分享一下: 一.系统自己的UITableView样式有两种: 1.UITableViewStylePlain: Plain样式的是方形的,充满你给的view.fra

  • UITableViewCell在编辑状态下背景颜色的修改方法

    本文主要介绍的是关于UITableViewCell在编辑状态下背景颜色的修改方法,分享出来供大家参考学习,下面来一起看看详细的介绍: 一.先看下效果图 二.网上很多下面这种答案 UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath]; cell.selectionStyle = UITableViewCellSelectionStyleNone; 这样设置,蓝色的选中图标也不会出现. 这种仅限于不编辑的时候,让Ta

  • iOS中使用UItableviewcell实现团购和微博界面的示例

    使用xib自定义UItableviewcell实现一个简单的团购应用界面布局 一.项目文件结构和plist文件 二.实现效果 三.代码示例 1.没有使用配套的类,而是直接使用xib文件控件tag值操作 数据模型部分: YYtg.h文件 复制代码 代码如下: // //  YYtg.h //  01-团购数据显示(没有配套的类) // //  Created by apple on 14-5-29. //  Copyright (c) 2014年 itcase. All rights reserv

  • iOS App开发中使用及自定义UITableViewCell的教程

    UITableView用来以表格的形式显示数据.关于UITableView,我们应该注意: (1)UITableView用来显示表格的可见部分,UITableViewCell用来显示表格的一行. (2)UITableView并不负责存储表格中的数据,而是仅仅存储足够的数据使得可以画出当前可见部分. (3)UITableView从UITableViewDelegate协议获取配置信息,从UITableViewDataSource协议获得数据信息. (4)所有的UITableView实现时实际上只有

  • iOS App开发中的UIStackView堆叠视图使用教程

    一.引言 随着autolayout的推广开来,更多的app开始使用自动布局的方式来构建自己的UI系统,autolayout配合storyBoard和一些第三方的框架,对于创建约束来说,已经十分方便,但是对于一些动态的线性布局的视图,我们需要手动添加的约束不仅非常多,而且如果我们需要插入或者移除其中的一些UI元素的时候,我们又要做大量的修改约束的工作,UIStackView正好可以解决这样的问题. 二.在storyBoard上初识StackView UIStackView是一个管理一组堆叠视图的控

  • iOS App开发中UIViewController类的使用教程

    一.引言 作为MVC设计模式中的C,Controller一直扮演着项目开发中最重要的角色,它是视图和数据的桥梁,通过它的管理,将数据有条有理的展示在我们的View层上.iOS中的UIViewController是UIKit框架中最基本的一个类.从第一个UI视图到复杂完整项目,都离不开UIViewController作为基础.基于UIViewController的封装和扩展,也能够出色的完成各种复杂界面逻辑.这里旨在讨论UIViewController的生命周期和属性方法,在最基础的东西上,往往会

  • iOS App开发中使cell高度自适应的黑魔法详解

    在使用 table view 的时侯经常会遇到这样的需求:table view 的 cell 中的内容是动态的,导致在开发的时候不知道一个 cell 的高度具体是多少,所以需要提供一个计算 cell 高度的算法,在每次加载到这个 cell 的时候计算出 cell 真正的高度. 在 iOS 8 之前 没有使用 Autolayout 的情况下,需要实现 table view delegate 的 tableView(tableView: UITableView, heightForRowAtInde

  • iOS App开发中Core Data框架基本的数据管理功能小结

    一.何为CoreData CoreData是一个专门用来管理数据的框架,其在性能与书写方便上都有很大的优势,在数据库管理方面,apple强烈推荐开发者使用CoreData框架,在apple的官方文档中称,使用CoreData框架可以减少开发者50%--70%的代码量,这虽然有些夸张,但由此可见,CoreData的确十分强大. 二.设计数据模型 在iOS开发中,时常使用SQL数据库对大量的表结构数据进行处理,但是SQL有一个十分明显的缺陷,对于常规数据模型的表,其处理起来是没问题的,例如一个班级表

  • iOS App开发中扩展RCLabel组件进行基于HTML的文本布局

    iOS系统是一个十分注重用户体验的系统,在iOS系统中,用户交互的方案也十分多,然而要在label中的某部分字体中添加交互行为确实不容易的,如果使用其他类似Button的控件来模拟,文字的排版又将是一个解决十分困难的问题.这个问题的由来是项目中的一个界面中有一些广告位标签,而这些广告位的标签却是嵌在文本中的,当用户点击文字标签的位置时,会跳转到响应的广告页. CoreText框架和一些第三方库可以解决这个问题,但直接使用CoreText十分复杂,第三方库多注重于富文本的排版,对类似文字超链接的支

  • iOS App开发中使用设计模式中的单例模式的实例解析

    一.单例的作用 顾名思义,单例,即是在整个项目中,这个类的对象只能被初始化一次.它的这种特性,可以广泛应用于某些需要全局共享的资源中,比如管理类,引擎类,也可以通过单例来实现传值.UIApplication.NSUserDefaults等都是IOS中的系统单例. 二.单例模式的两种写法 1,常用写法 #import "LGManagerCenter.h" static LGManagerCenter *managerCenter; @implementation LGManagerCe

  • 实例解析设计模式中的外观模式在iOS App开发中的运用

    外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义 一个高层接口,这个接口使得这一子系统更加容易使用. 下面给大家展示一下类的结构图,想必大家一看就明白了: 其实这个模式中,没有类与类之间的继承关系,只是进行了简单的类引用,统一了对外的接口而已.看起来是不是很简单?废话不多说了,下面简单向大家展示一下代码吧! 注意:本文所有代码均在ARC环境下编译通过. SubSystemOne类接口 复制代码 代码如下: #import <Foundation/Foundation.

  • iOS App开发中修改UILabel默认字体的方法

    在项目比较成熟的基础上,遇到了这样一个需求,应用中需要引入新的字体,需要更换所有Label的默认字体,但是同时,对于一些特殊设置了字体的label又不需要更换.乍看起来,这个问题确实十分棘手,首先项目比较大,一个一个设置所有使用到的label的font工作量是巨大的,并且在许多动态展示的界面中,可能会漏掉一些label,产生bug.其次,项目中的label来源并不唯一,有用代码创建的,有xib和storyBoard中的,这也将浪费很大的精力.这种情况下,我们可能会有下面两种处理方式. 一.普通方

  • iOS App开发中UISearchBar搜索栏组件的基本用法整理

    基本属性 复制代码 代码如下: @UISearchBar search = [[UISearchBar alloc]initWithFrame:CGRectMake(0,44,320,120)]; pragma mark -基本设置 复制代码 代码如下: //控件的样式 默认--0白色,1是黑色风格 /* UIBarStyleDefault          = 0, UIBarStyleBlack            = 1, search.barStyle =UIBarStyleDefau

随机推荐