码迷,mamicode.com
首页 > 移动开发 > 详细

IOS开发指南 第6章 表视图 学习

时间:2015-09-18 13:51:00      阅读:264      评论:0      收藏:0      [点我收藏+]

标签:

1 概述

  结构:表头视图(table header view),表脚视图(table footer view),节(section),单元格(cell) 

  相关类:UITableViewCell UITableViewController UITableViewHeaderFooterView 委托协议和数据源协议

  分类:普通表视图:用于动态表

           分组表视图:用于静态表,进行界面布局

  单元格的组成:图标 标题 拓展视图

             样式:拓展视图由枚举类型UITableViewCellAccessoryType定义

                     单元格样式由枚举UITableViewCellStyle定义

2 简单表视图

  必须实现:-tableView:numberOfRowsInSection:表视图显示的时候发出,询问当前节中的行数

                -tableView:cellForRowAtIndexPath:单元格显示的时候发出,为单元格提供数据

  表视图的创建是在实例化表视图控制器的时候完成的

  cell的属性:textLabel detailTextLabel imageView

#pragma mark --UITableViewDataSource 协议方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.listTeams count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   代码和interface builder结合的方式实现cell 的可重用机制
cell 的样式和identifier都在属性中设置
static NSString *CellIdentifier = @"CellIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // if (cell == nil) { // cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; // } NSUInteger row = [indexPath row];获得当前的行数 NSDictionary *rowDict = [self.listTeams objectAtIndex:row]; cell.textLabel.text = [rowDict objectForKey:@"name"]; NSString *imagePath = [rowDict objectForKey:@"image"]; imagePath = [imagePath stringByAppendingString:@".png"]; cell.imageView.image = [UIImage imageNamed:imagePath]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; return cell; }

3 自定义单元格

 准备:选择size class-在故事板自定义单元格-添加约束-创建自定义单元格类-关联到故事板中的cell-在Custom Cell类中为自定义的控件添加输出口

 代码:在-tableView:cellForRowAtIndexPath:中为新的cell内部单元添加数据

4 添加搜索栏 UISearchBar UISearchBarDelegate

  添加SearchBar:注意不能将SearchBar拖到单元格内部

  设置SearchBar属性,定义输出口,设置委托

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //设置搜索栏委托对象为当前视图控制器
    self.searchBar.delegate = self;
    
    //设定搜索栏ScopeBar隐藏
    self.searchBar.showsScopeBar = NO;
    [self.searchBar sizeToFit];
    
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *plistPath = [bundle pathForResource:@"team"
                                           ofType:@"plist"];
    //获取属性列表文件中的全部数据
    self.listTeams = [[NSArray alloc] initWithContentsOfFile:plistPath];
    
    //初次进入查询所有数据
    [self filterContentForSearchText:@"" scope:-1];
}

搜索方法:(一个单纯的工具方法)

NSpredict  -prefictWithFormat:构建搜索条件

-filterArrayUsingPredict:过滤结果

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSUInteger)scope;
{
    
    if([searchText length]==0)
    {
        //查询所有
        self.listFilterTeams = [NSMutableArray arrayWithArray:self.listTeams];
        return;
    }
    
    NSPredicate *scopePredicate;
    NSArray *tempArray ;
    
    switch (scope) {
        case 0: //英文 image字段保存英文名 SELF代表要查询的对象 SELF.image代表要查询的对象的image字段contains[c]代表不区分大小写
            scopePredicate = [NSPredicate predicateWithFormat:@"SELF.image contains[c] %@",searchText];
            tempArray =[self.listTeams filteredArrayUsingPredicate:scopePredicate];
            self.listFilterTeams = [NSMutableArray arrayWithArray:tempArray];
            
            break;
        case 1: //中文 name字段是中文名
            scopePredicate = [NSPredicate predicateWithFormat:@"SELF.name contains[c] %@",searchText];
            tempArray =[self.listTeams filteredArrayUsingPredicate:scopePredicate];
            self.listFilterTeams = [NSMutableArray arrayWithArray:tempArray];
            break;
        default:
            //查询所有
            self.listFilterTeams = [NSMutableArray arrayWithArray:self.listTeams];
            break;
    }
}

***************

关于NSPredict的概念http://blog.csdn.net/ztp800201/article/details/8116081

正则表达式https://msdn.microsoft.com/zh-cn/library/ae5bf541(VS.80).aspx

***************

实现代理方法

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
属性:searchBar.text searchBar.selectedScopeButtonIndex
#pragma mark --UISearchBarDelegate 协议方法
//  获得焦点,成为第一响应者
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
    self.searchBar.showsScopeBar = TRUE;
    [self.searchBar sizeToFit];
    return YES;
}
//点击键盘上的搜索按钮
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    self.searchBar.showsScopeBar = NO;
    [self.searchBar sizeToFit];
    [self.searchBar resignFirstResponder];
}
//点击搜索栏取消按钮
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    //查询所有
    [self filterContentForSearchText:self.searchBar.text scope:-1];
    self.searchBar.showsScopeBar = NO;
    [self.searchBar sizeToFit];
    [self.searchBar resignFirstResponder];
}

//当文本内容发生改变时候调用
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    [self filterContentForSearchText:self.searchBar.text scope:self.searchBar.selectedScopeButtonIndex];
    [self.tableView reloadData];
}

//当搜索范围选择发生变化时候调用
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope搜索范围栏中的按钮索引
{
    [self filterContentForSearchText:self.searchBar.text scope:selectedScope];
    [self.tableView reloadData];
}

4 分节表视图 

  分节是添加索引和分组的前提

  -numberOfSectionInTableView:

  -tableView:titleForHeader/FooterInSection:

  1)添加索引 一般不再使用拓展视图

       排序:sortedArrayUsingSelector:

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *plistPath = [bundle pathForResource:@"team_dictionary"
                                           ofType:@"plist"];
    //获取属性列表文件中的全部数据
    self.dictData = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
    
    NSArray* tempList  = [self.dictData allKeys];
    //对key进行排序
    self.listGroupname = [tempList sortedArrayUsingSelector:@selector(compare:)];
}

     实现委托:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [self.listGroupname count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    NSString *groupName = [self.listGroupname objectAtIndex:section];
    return groupName;
}

   添加索引:-sectionIndexTitlesForTableView:

-(NSArray *) sectionIndexTitlesForTableView: (UITableView *) tableView
{
    NSMutableArray *listTitles = [[NSMutableArray alloc] initWithCapacity:[self.listGroupname count]];
    //把 A组 -> A
    for (NSString *item in self.listGroupname) {
        NSString *title = [item  substringToIndex:1];
        [listTitles  addObject:title];
    }
    return listTitles;
}

  2)静态表与控制界面布局

     准备:在TableView的属性检查器将Content设为Static Cells,设置Section数,Style设为Grouped

              拖拽控件到Cell里

     代码:viewController中编辑

     在静态表中无需实现数据源和委托协议方法

5 修改单元格

   1)删除与插入

       -setEditing:animated:设定视图能否进入编辑状态

       -tableView:editingStyleForRowAtIndexPath:进行单元格编辑图标的设置

       -tableView:commitEditingStyle:forRowAtIndexPath:实现删除或插入的处理

       -reloadData 刷新数据

      插入单元格时,应该有个控件能接受用户输入的信息:先在Root View Controller Sence中添加TextFiled,为其添加输出口,之后会利用cell.contentView.addSubview来实现添加。

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //设置导航栏
编辑按钮样式的切换取决于当前视图的编辑状态,点击按钮会调用setEditing:animated:方法 self.navigationItem.rightBarButtonItem = self.editButtonItem; self.navigationItem.title = @"单元格插入和删除"; //设置单元格文本框 self.txtField.hidden = YES; self.txtField.delegate = self; 声明是可变数组方便对其进行删除或修改 self.listTeams = [[NSMutableArray alloc] initWithObjects:@"黑龙江", @"吉林", @"辽宁", nil]; }

    点击按钮回调:确认视图能不能进入编辑状态

#pragma mark -- UIViewController生命周期方法,用于响应视图编辑状态变化
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    点击按钮tableView处于编辑状态,textFiela显示出来
    [self.tableView setEditing:editing animated:YES];
    if (editing) {
        self.txtField.hidden = NO;
    } else {
        self.txtField.hidden = YES;
    }
}

 

  实现委托协议:

    为插入准备一个空单元格

#pragma mark --UITableViewDataSource 协议方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.listTeams count] + 1;
}

   单元格数据要分为两种情况:普通单元格和要插入的那个单元格,在插入的那个中添加文本框

 

 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    row是从0开始的count是array中元素数量,所以相等的那个就是要编辑的那个,这里的逻辑用YES和NO来表示比较好
    BOOL b_addCell = (indexPath.row == self.listTeams.count);
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:CellIdentifier] ;
    }
    
    if (!b_addCell) {
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
        cell.textLabel.text = [self.listTeams objectAtIndex:indexPath.row];
    } else {
        self.txtField.frame = CGRectMake(10,0,300,44);
        self.txtField.borderStyle = UITextBorderStyleNone;
        self.txtField.placeholder = @"Add...";
        self.txtField.text = @"";
        [cell.contentView addSubview:self.txtField];
    }
    
    return cell;
}

 

实现三步走之后两步: 

   设定编辑图标:

#pragma mark --UITableViewDelegate 协议方法

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == [self.listTeams count]) {
        return UITableViewCellEditingStyleInsert;
    } else {
        return UITableViewCellEditingStyleDelete;
    }
}
编辑单元格显示暗淡
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == [self.listTeams count]) {
        return NO;
    } else {
        return YES;
    }
}

  确认编辑样式实现编辑:

   -removeObiectAtIndex:

   -delegateRowsAtIndexPaths:withRowAnimation:

   -insertRowsAtIndexPaths:withRowAnimation:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray* indexPaths = [NSArray arrayWithObject:indexPath];
    编辑的实质是在数据来源(数据库)中实现删除与插入
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [self.listTeams removeObjectAtIndex: indexPath.row];
        [self.tableView deleteRowsAtIndexPaths:indexPaths
                              withRowAnimation:UITableViewRowAnimationFade];
        
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        
        [self.listTeams insertObject:self.txtField.text atIndex:[self.listTeams count]];
        [self.tableView insertRowsAtIndexPaths:indexPaths
                              withRowAnimation:UITableViewRowAnimationFade];
        
    }刷新数据
    [self.tableView reloadData];
    
}

  2)移动单元格:单元格重新排序

   -setEditing:animated:

   -tableView:editing

   -tableView:canMoveRowAtIndexPath:

   -tableView:moveRowAtIndexPath:

 

 

 

 

 

 

 

 

 

 

 

  

 

 

 

  

 

IOS开发指南 第6章 表视图 学习

标签:

原文地址:http://www.cnblogs.com/haugezi/p/4818922.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!