Managing Selections

管理选择

When users tap a row of a table view, usually something happens as a result. Another table view could slide into place, the row could display a checkmark, or some other action could be performed. The following sections describe how to respond to selections and how to make selections programmatically.

当用户点击表格视图的一行时,通常会发生一些事情。 另一个表格视图可以滑入到位,行可以显示一个勾选标记,或者其它一些操作可能执行。 以下章节描述了如何响应选择以及如何通过程序做选择。

Selections in Table Views

一、在表格视图中选择

There are a few human-interface guidelines to keep in mind when dealing with cell selection in table views:

当你在表格视图里处理单元格选择时一些人机界面(human-interface)指南需要牢记:

  • You should never use selection to indicate state. Instead, use check marks and accessory views for showing state.

    你绝不应该使用选择来表示状态。作为替代,你可以使用复选标记和辅助视图来显示状态。

  • When the user selects a cell, you should respond by deselecting the previously selected cell (by calling the deselectRowAtIndexPath:animated: method) as well as by performing any appropriate action, such as displaying a detail view.

    当用户选择一个单元格,你应该通过取消选择前一个被选择的单元格来响应(通过调用deselectRowAtIndexPath:animated:方法),以及通过执行任何正确的操作,比如显示一个详细视图等。

  • If you respond to the the selection of a cell by pushing a new view controller onto the navigation controller’s stack, you should deselect the cell (with animation) when the view controller is popped off the stack.

    如果你通过把一个新的视图控制器压入导航控制器栈来响应一个单元格的选择, 那么当视图控制器从栈中弹出时,你应该取消选择单元格(用动画)。

You can control whether rows are selectable when the table view is in editing mode by setting the allowsSelectionDuringEditing property of UITableView. In addition, beginning with iOS 3.0, you can control whether cells are selectable when editing mode is not in effect by setting the allowsSelection property.

当表格视图处于编辑模式时,你可以通过设置UITableView的allowsSelectionDuringEditing 特性来控制行是否可选择。 此外,从iOS3.0开始,当编辑模式不受allowsSelection特性的设置影响时,你可以控制单元格是否可选。

Responding to Selections

二、响应选择

Users tap a row in a table view either to signal to the application that they want to know more about what that row signifies or to select what the row represents. In response to the user tapping a row, an application could do any of the following:

用户在表格视图里点击一行来提示应用程序他们想要了解该行的更多信息或者来选择该行所代表的内容。 应用程序可以实现以下任何操作来响应用户点击一行:

  • Show the next level in a data-model hierarchy.

    显示数据模型层次中的下一层。

  • Show a detail view of an item (that is, a leaf node of the data-model hierarchy).

    显示一个数据项的详细视图(就是数据模型层次的一个叶节点)。

  • Show a checkmark in the row to indicate that the represented item is selected.

    在行中显示一个复选标记来表明代表数据项被选中。

  • If the touch occurred in a control embedded in the row, it could respond to the action message sent by the control.

    如果点击发生在一行中内嵌的控件中,它可以响应该控件发送的操作消息。

To handle most selections of rows, the table view’s delegate must implement the tableView:didSelectRowAtIndexPath: method. In sample method implementation shown in Listing 6-1, the delegate first deselects the selected row. Then it allocates and initializes an instance of the next table-view controller in the sequence. It sets the data this view controller needs to populate its table view and then pushes this object onto the stack maintained by the application’sUINavigationController object.

要想处理大多数行的选择,表格视图的委托必须实现tableView:didSelectRowAtIndexPath: 方法。 在列表6-1中显示了一个示例方法实现,委托首先取消选择被选择的行。 然后它在队列中分配和初始化下一个表格视图控制器的实例。 它设置该视图控制器用来填充(populate)其表格视图的数据,然后通过应用程序的UINavigationController对象把该对象压入栈。

Listing 6-1  Responding to a row selection

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
     [tableView deselectRowAtIndexPath:indexPath animated:NO];
     BATTrailsViewController *trailsController = [[BATTrailsViewController alloc] initWithStyle:UITableViewStylePlain];
     trailsController.selectedRegion = [regions objectAtIndex:indexPath.row];
     [[self navigationController] pushViewController:trailsController animated:YES];
}

If a row has a disclosure control—the white chevron over a blue circle—for an accessory view, clicking the control results in the delegate receiving atableView:accessoryButtonTappedForRowWithIndexPath: message (instead of tableView:didSelectRowAtIndexPath:). The delegate responds to this message in the same general way as it does for other kinds of selections.

如果行中有一个下拉控件(disclosure control)---蓝色圈圈里有一个白色v型标记---表示一个附属视图,在tableView:accessoryButtonTappedForRowWithIndexPath: 消息(而不是在tableView:didSelectRowAtIndexPath:)中接收到的委托中点击控件结果。委托以跟别的类型的选择一样的通用方式响应该消息。

A row can also have a control object as its accessory view, such as a switch or a slider. This control object functions as it would in any other context: Manipulating the object in the proper way results in an action message being sent to a target object. Listing 6-2 illustrates a data source object that adds a UISwitch object as a cell’s accessory view and then responds to the action messages sent when the switch is “flipped.”

行还可以有一个控件对象作为它的辅助视图,比如一个开关或一个滑动条。 该控件对象跟它在其它上下文(context)中有一样的功能:以正确的方式操作对象让某个动作消息被发送到某个目标对象。 列表6-2 演示了一个数据源对象,它添加一个UISwitch 对象作为一个单元格的辅助视图,然后当开关被按下时响应操作消息。

Listing 6-2  Setting a switch object as an accessory view and responding to its action message

列表6-2 把一个开关对象设置为一个辅助视图并响应它的操作消息。

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
       UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:@"CellWithSwitch"];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellWithSwitch"];
            cell.selectionStyle = UITableViewCellSelectionStyleNone;
            cell.textLabel.font = [UIFont systemFontOfSize:14];
        }
        UISwitch *switchObj = [[UISwitch alloc] initWithFrame:CGRectMake(1.0, 1.0, 20.0, 20.0)];
        switchObj.on = YES;
        [switchObj addTarget:self action:@selector(toggleSoundEffects:) forControlEvents:(UIControlEventValueChanged | UIControlEventTouchDragInside)];
        cell.accessoryView = switchObj;
 
        cell.textLabel.text = @"Sound Effects";
        return cell;
}
 
- (void)toggleSoundEffects:(id)sender {
    [self.soundEffectsOn = [(UISwitch *)sender isOn];
    [self reset];
}

You may also define controls as accessory views of table-view cells created in Interface Builder. Drag a control object (switch, slider, and so on) into anib document window containing a table-view cell. Then, using the connection window, make the control the accessory view of the cell. “Loading Table View Cells from a Storyboard” describes the procedure for creating and configuring table-view cell objects in nib files.

你还可以在界面生成器里定义各种控件成为表格视图单元格的辅助视图。 把一个控件对象(开关,滑动条等等)拖到包含一个表格视图单元格的nib文件窗口中。 然后使用连接窗口(connection window)设置单元格的辅助视图控件。 “Loading Table View Cells from a Storyboard” 描述了如何在nib文件中创建和配置表格视图单元格对象。

Selection management is also important with selection lists. There are two kinds of selection lists:

选择管理对于选择列表同样重要。 以下是两种选择列表:

  • Exclusive lists where only one row is permitted the checkmark

    单元列表只允许选中一行。

  • Inclusive lists where more than one row can have a checkmark

    多选列表允许选中多行。

Listing 6-3 illustrates one approach to managing an exclusive selection list. It first deselects the currently selected row and returns if the same row is selected; otherwise it sets the checkmark accessory type on the newly selected row and removes the checkmark on the previously selected row

列表6-3 显示了管理一个单选列表的方法。 如果选中了同一行,它首先取消选择单前被选择的行,然后返回;否则它给新选择的行打上勾,并取消之前被选择行中的勾。

Listing 6-3  Managing a selection list—exclusive list

列表 6-3 管理一个选择列表---单选列表

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
    NSInteger catIndex = [taskCategories indexOfObject:self.currentCategory];
    if (catIndex == indexPath.row) {
        return;
    }
    NSIndexPath *oldIndexPath = [NSIndexPath indexPathForRow:catIndex inSection:0];
 
    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
    if (newCell.accessoryType == UITableViewCellAccessoryNone) {
        newCell.accessoryType = UITableViewCellAccessoryCheckmark;
        self.currentCategory = [taskCategories objectAtIndex:indexPath.row];
    }
 
    UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:oldIndexPath];
    if (oldCell.accessoryType == UITableViewCellAccessoryCheckmark) {
        oldCell.accessoryType = UITableViewCellAccessoryNone;
    }
}

Listing 6-4 illustrates how to manage a inclusive selection list. As the comments in this example indicate, when the delegate adds a checkmark to a row or removes one, it typically also sets or unsets any associated model-object attribute.

列表 6-4 演示了如何管理一个多选列表。 正如在该例子中的注释所示,当委托给一行添加勾选标记或删除一个勾选标记时,通常还会设置或取消设置任何相关的模型对象属性。

Listing 6-4  Managing a selection list—inclusive list

列表 6-4 管理一个选择列表--多选列表

- (void)tableView:(UITableView *)theTableView
          didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath {
 
    [theTableView deselectRowAtIndexPath:[theTableView indexPathForSelectedRow] animated:NO];
    UITableViewCell *cell = [theTableView cellForRowAtIndexPath:newIndexPath];
    if (cell.accessoryType == UITableViewCellAccessoryNone) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        // Reflect selection in data model
    } else if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
        cell.accessoryType = UITableViewCellAccessoryNone;
        // Reflect deselection in data model
    }
}

In tableView:didSelectRowAtIndexPath: you should always deselect the currently selected row.

tableView:didSelectRowAtIndexPath: 中,你应该总是取消选择当前已被选择的行。

Programmatically Selecting and Scrolling

三、通过程序实现选择和滚动

Occasionally the selection of a row originates within the application itself rather than from a tap in a table view. There could be an externally induced change in the data model. For example, the user adds a new person to an address book and then returns to the list of contacts; the application wants to scroll this list to the recently added person. For situations like these, you can use the UITableView methods selectRowAtIndexPath:animated:scrollPosition: and (if the row is already selected) scrollToNearestSelectedRowAtScrollPosition:animated:. You may also call scrollToRowAtIndexPath:atScrollPosition:animated:if you want to scroll to a specific row without selecting it.

行的选择偶尔会在应用程序由自身激活而不是在一个表格视图的一个点击。 它有可能是在数据模型中由外部引发的变化。 比如,用户给联络簿里添加了一个新人,然后返回到联系人列表;应用程序想要把列表滚动到最近添加的联系人那。 对已类似这样的情况,你可以使用UITableView方法selectRowAtIndexPath:animated:scrollPosition: 以及(如果行已被选择)scrollToNearestSelectedRowAtScrollPosition:animated:. 方法。 如果你想要把列表滚动到某行但不选择它,你还可以调用scrollToRowAtIndexPath:atScrollPosition:animated: 方法。

The code in Listing 6-5 (somewhat whimsically) programmatically selects and scrolls to a row 20 rows away from the just-selected row using theselectRowAtIndexPath:animated:scrollPosition: method.

列表6-5中的代码通过selectRowAtIndexPath:animated:scrollPosition: 方法 实现列表从刚选择的行滚动到第20行并选择该行。

Listing 6-5  Programmatically selecting a row

列表6-5 通过程序选择某行

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)newIndexPath {
    NSIndexPath *scrollIndexPath;
    if (newIndexPath.row + 20 < [timeZoneNames count]) {
        scrollIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row+20 inSection:newIndexPath.section];
    } else {
        scrollIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row-20 inSection:newIndexPath.section];
    }
    [theTableView selectRowAtIndexPath:scrollIndexPath animated:YES
                        scrollPosition:UITableViewScrollPositionMiddle];
}

Table View Programming Guide for iOS---(七)---Managing Selections的更多相关文章

  1. 【IOS笔记】View Programming Guide for iOS -1

    原文:View Programming Guide for iOS View and Window Architecture Views and windows present your applic ...

  2. View Programming Guide for iOS ---- iOS 视图编程指南(四)---Views

    Views Because view objects are the main way your application interacts with the user, they have many ...

  3. Table View Programming Guide for iOS---(一)---About Table Views in iOS Apps

    About Table Views in iOS Apps Table views are versatile user interface objects frequently found in i ...

  4. Table View Programming Guide for iOS---(四)---Navigating a Data Hierarchy with Table Views

    Navigating a Data Hierarchy with Table Views 导航数据表视图层次 A common use of table views—and one to which ...

  5. View Programming Guide for iOS ---- iOS 视图编程指南(二)---View and Window Architecture

    View and Window Architecture 视图和窗口架构 Views and windows present your application’s user interface and ...

  6. View Programming Guide for iOS ---- iOS 视图编程指南(一)

    Next About Windows and Views 关于窗口和视图 In iOS, you use windows and views to present your application’s ...

  7. View Programming Guide for iOS ---- iOS 视图编程指南(五)---Animations

      Animations Animations provide fluid visual transitions between different states of your user inter ...

  8. Table View Programming Guide for iOS---(三)----Overview of the Table View API

    Overview of the Table View API 表格视图API概述 The table view programming interface includes several UIKit ...

  9. Table View Programming Guide for iOS---(五)---Creating and Configuring a Table View

    Creating and Configuring a Table View Your app must present a table view to users before it can mana ...

随机推荐

  1. Oracle EBS - 工单状态

    Job status update 1. Job的几种状态 unreleased --未核发 released--已核发 complete --完成 complete no charges--完成不计 ...

  2. Solidworks 不能生成实体,因为这将导致厚度为零的零件怎么办

    如下图所示,我认为我长出一块东西根本不会对其他零件有什么影响.   去掉合并结果之后就好了.   钣金要比方钢高出1mm,这样焊接上去才方便.              

  3. [原创] 在线音乐API的研究 (Part 2.1)

    最近,在优化一个自己写的音乐播放器.主要目的是回顾.归纳,并希望能够写出一个属于自己的common lib.今天,主要是关于在线音乐API的一些分析结果.此次,主要分析的是歌词.专辑部分.在线搜索音乐 ...

  4. 【转载】C# 理解泛型

    术语表 generics:泛型type-safe:类型安全collection: 集合compiler:编译器run time:程序运行时object: 对象.NET library:.Net类库va ...

  5. Cocoapods Undefined symbols for architecture armv7s\arm64

    此类错误 "_OBJC_CLASS_$_AFURLSessionManager", referenced from: 解决的方法 在other linker flags里加入一行 ...

  6. oracle SQL语句(转)

    Oracle数据库语句大全 ORACLE支持五种类型的完整性约束 NOT NULL (非空)--防止NULL值进入指定的列,在单列基础上定义,默认情况下,ORACLE允许在任何列中有NULL值. CH ...

  7. flask-本地线程-请求上下文补充

    context(上下文)是flask里面非常好的设计,使用flask需要非常理解应用上下文和请求上下文这两个概念 本地线程 本地线程(thread local)希望不同的线程对于内容的修改只在线程内部 ...

  8. win10安装Anaconda+TensorFlow+配置PyCharm

    其实很简单,我这里也只是记录一下而已. 第一大坑:anaconda必须安装4.2以前的版本,不能安装4.3以后的 版本:满满的血泪史 因为我们需要安装自带的python必须是3.5,才可以调用Tens ...

  9. 梳理caffe代码common(八)

    因为想梳理data_layer的过程.整理一半发现有几个很重要的头文件就是题目列出的这几个: 追本溯源,先从根基開始学起.这里面都是些什么鬼呢? common类 命名空间的使用:google.cv.c ...

  10. 《ASP.NET》数据绑定—DataList

    DataList控件是.NET中的一个控件.DataList控件以表的形式呈现数据(在属性生成器中能够编辑),通过该控件,您能够使用不同的布局来显示数据记录(使用模板编辑).比如,将数据记录排成列或行 ...