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. SolidEdge 装配体中如何快速的搞定一个面上所有螺丝 如何在装配体上进行阵列

    1 点击"规则排列" 选择要排列的螺丝   2 选择被规则排列的架子   3 选择所有的圆孔(鼠标滑到任意圆孔位置,左键单击即可选中所有圆孔)   4 选择参考的基准孔(已经上了螺 ...

  2. JAVA设计模式之单例模式(转)

    本文继续介绍23种设计模式系列之单例模式. 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单 ...

  3. 整理对Spark SQL的理解

    Catalyst Catalyst是与Spark解耦的一个独立库,是一个impl-free的运行计划的生成和优化框架. 眼下与Spark Core还是耦合的.对此user邮件组里有人对此提出疑问,见m ...

  4. mybatis 简单项目步骤

    mybatis.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configura ...

  5. CustomView

    https://github.com/eltld/CustomView

  6. 修改flash builder注释里的@author

    在flash builder里,按Ctrl+Shift+D可以很方便在添加AsDoc注释.可是有些生成的@author是系统的用户名(如:administor),怎么修改这个为自己的名字呢? Step ...

  7. hadoop 一些文件操作

    在HDFS上面,FileSystem创建目录 复制本地文件到HDFS 获取集群中的节点

  8. 新装Linux系统没有网卡驱动的解决办法和步骤

    Linux下查看网卡驱动和版本信息 - CSDN博客 https://blog.csdn.net/guyan1101/article/details/72770424/ 检查网卡是否加载 - Linu ...

  9. redis的图形界面管理工具

    大部分人都知道redis是一款用在缓存服务器上的软件,它与memcache类似,都可以存储海量的数据,用在大访问量的web网站.聊天记录存放等方面,但是又与memcache不同: 1.缓存数据可以持久 ...

  10. 提升自身的iOS编程水平 (转载)

    阅读博客 在现在这个碎片化阅读流行的年代,博客的风头早已被微博盖过.而我却坚持写作博客,并且大量地阅读同行的iOS开发博客.博客的文章长度通常在3000字左右,许多iOS开发知识都至少需要这样的篇幅才 ...