iOS 委托和数据源

示例

的UITableViewDelegate用于控制如何显示表,并UITableViewDataSource用来定义UITableView的数据。有两种必需的方法,许多可选的方法可用于自定义大小,部分,标题和单元格UITableView。


UITableViewDataSource

所需方法

numberOfRowsInSection: 此方法定义在表格视图的每个部分中将显示多少个单元格。

目标C

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    //返回表视图的行数。通常是从数组填充的
    // 或可以静态定义。
    return self.myArray.count;
}

迅捷3

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    //返回表视图的行数。通常是从数组填充的 
    // 或可以静态定义。
    return self.myArray.count
}

cellForRowAtIndexPath:此方法是UITableView创建和配置的单元格的地方。应该返回一个UITableViewCell或自定义子类。

注:使用dequeueReusableCellWithIdentifier:forIndexPath:要求类或笔尖已登记使用该标识符UITableView的registerClass:forCellReuseIdentifier:或registerNib:forCellReuseIdentifier:方法。通常,这将通过UIViewController的viewDidLoad方法来完成。

目标C

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCustomCell" 
                                                         forIndexPath:indexPath];
    
    // 所有其他定制都在这里
    cell.titleLabel.text = [NSString stringWithFormat:@"Title Row %lu", indexPath.row];

    return cell;
}

迅捷3

func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("MyCustomCell", forIndexPath:indexPath)
    
    // 所有其他定制都在这里
    cell.titleLabel.text = String(format:"Title Row %lu", indexPath.row)
    
    return cell
}
可选方法

titleForHeaderInSection:在表视图中为每个节标题定义一个字符串作为标题。此方法仅允许更改标题,可以通过定义标题的视图来进行进一步的自定义。

目标C

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    switch(section) {
        case 0:
            return @"Title 1";
            break;

        case 1:
            return @"Title 2";
            break;

        default:
            return nil;
            break;
    }
}

迅捷3

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    switch section {
        case 0:
            return "Title 1"
        case 1:
            return "Title 2"
        default:
            return nil
    }
}

titleForFooterInSection: 在表视图中为每个节标题定义一个字符串作为标题。

目标C

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
    return @"Footer text";
}

迅捷3

func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
    return "Footer text"
}

canEditRowAtIndexPath:用于确定是否应为指定的行显示编辑UI。如果YES可以删除或添加指定的行,则应返回。

目标C

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

迅捷3

func tableView(_ tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}

commitEditingStyle:forRowAtIndexPath应该执行处理添加或删除指定行所需的工作。例如,从UITableViewwith动画中删除单元格,然后从表的数据模型中删除关联的对象。

目标C

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    switch (editingStyle) {
        case UITableViewCellEditingStyleInsert:
            // 在此处将新数据插入支持数据模型
            [self insertNewDataIntoDataModel];
            [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            break;
        case UITableViewCellEditingStyleDelete:
            [self removeDataFromDataModelAtIndex:indexPath.row];
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            break;
        default:
            // 如果editingStyle既不是Insert也不是Delete,则什么也不执行
            break;

    }
}

迅捷3

func tableView(_ tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    switch editingStyle {
        case .Insert:
            self.insertNewDataIntoDataModel()
            tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation:.Automatic)
        case .Delete:
            self.removeDataFromDataModelAtIndex(indexPath.row)
            tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation:.Automatic)
        default:
            // 如果editingStyle既不是Insert也不是Delete,则什么也不执行
    }
}

editActions:forRowAt允许将附加动作或按钮添加到内一行的编辑模式UITableview。例如,如果您需要两个按钮,当用户滑动以编辑行时需要一个编辑和删除按钮,则可以使用此方法。

迅捷3

override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    // 在处理程序中,您将传递操作以及用于的indexPath 
    // 正在编辑的行 
    let editAction = UITableViewRowAction(style: .normal, title: "Edit", handler: { [unowned self] action, indexPath in
        // 轻按编辑时执行某些操作
    })
    
    // 更改编辑动作的颜色
   editAction.backgroundColor= UIColor.blue
        
    let deleteAction = UITableViewRowAction(style: .destructive, title: "Delete", handler: { [unowned self] action, indexPath in
        // 处理删除事件
    })
        
        
    return [deleteAction, editAction]
}


UITableViewDelegate

中的所有方法UITableViewDelegate都是可选的,但是实现它们的委托将为启用其他功能UITableView。

numberOfSectionsInTableView: 默认情况下,它返回1,但是通过返回不同数量的节来启用多节支持。

目标C

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return self.numSections;
}

迅捷3

func numberOfSectionsInTableView(_ tableView: UITableView) -> Int {
    return self.numSections
}

viewForHeaderInSection 允许将自定义视图配置为该部分的标题。

目标C

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(tableView.frame), 22)];
   view.backgroundColor= [UIColor groupTableViewBackgroundColor];
    
    UILabel *label = [[UILabel alloc] init];
   label.font= [UIFont systemFontOfSize:12];
   label.textColor= [UIColor darkGrayColor];
    
    switch (section) {
        case 1: {
           label.text= @"Title";
           label.frame= labelFrame;
            
            UIButton *more = [[UIButton alloc] initWithFrame:btnFrame];
            [more setTitle:@"See more" forState:UIControlStateNormal];
            [more.titleLabel setFont:[UIFont systemFontOfSize:12]];
            [view addSubview:more];
        }   break;
            
        default:
           label.frame= CGRectMake(0, 0, 0, 0);
            break;
    }
    
    [view addSubview:label];
    return view;
}

迅捷3

func tableView(_ tableView: UITableView,  viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 22))
   view.backgroundColor= UIColor.groupTableViewBackgroundColor()
    
    let label = UILabel()
   label.font= UIFont.systemFontOfSize(12)
   label.textColor= UIColor.darkGrayColor()
    
    switch section {
        case 1:
           label.text= "Title"
           label.frame= labelFrame
            
            let more = UIButton(frame: btnFrame)
            more.setTitle("See more", forState:.Normal)
            view.addSubview(more)
            
        default:
           label.frame= CGRect.zero
    }
    
    view.addSubview(label)
    return view;
}

heightForRowAtIndexPath: 在表格视图中定义每个单元格的高度。

目标C

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

迅捷3

func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 44
}

heightForHeaderInSection:并heightForFooterInSection在表格视图中定义每个节的页眉和页脚的高度

目标C

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 33;
}

迅捷3

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 33
}