您好,登录后才能下订单哦!
Mark Items as Completed
给项目添加完成标记
如果你永远不标记事项完成,那么待办事宜清单就不够好。现在,你将添加这项支持。一个简单的接口将完成状态的切换当用户点击表单元并且让完成项显示完成标记。幸运的是,表视图有一些内建的行为能让你利用用来实现简单的接口——显然,当用户点击表单元的时候表视图会通知它们的委托。因此,任务是编写代码,应对用户在表中点击待办事宜项。
当你在故事板中设置表格时,Xcode已经为表视图设置了XYZToDoListViewController:的委托。你所要做的就是实现tableView:didSelectRowAtIndexPath:委托方法来响应用户点击和正确更新你的待办事宜清单项。
当表单元被选中后,表视图调用tableView:didSelectRowAtIndexPath:委托方法来看应该如何处理选择。在这个方法中,你将写一些代码来更新待办事宜项的完成状态。
为项完成或未完成添加标记
1.在工程导航器中选择XYZToDoListViewController.m.
2.在 @end 前面添加如下代码:
#pragma mark - Table view delegate
-(void)tableView:(UITableView*)tableViewdidSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
}
尝试输入第二行,而不是粘贴复制。你将会发现Xcode完成代码的一个很节省时间特性。当Xcode带有潜在完成的列表的时候,滚动这个列表直到你找到你想输入的哪一行然后点击回车。Xcode会为你输入整行。
5.你想响应点击但不是真的离开表单元选择。添加如下代码会在选择后立刻取消选择。
.[tableViewdeselectRowAtIndexPath:indexPathanimated:NO];
6.
7.
8.在你的toDoItems数组中找到相应的XYZToDoItem。
.XYZToDoItem*tappedItem=[self.toDoItemsobjectAtIndex:indexPath.row];
9.
10.
11.开关被点击项的完成状态。
.tappedItem.completed=!tappedItem.completed;
12.
13.
14.告诉表视图重新加载你刚刚更新的行的数据。
.[tableViewreloadRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationNone];
15.
16.
你的tableView:didSelectRowAtIndexPath:方法看上去如下:
.-(void)tableView:(UITableView*)tableViewdidSelectRowAtIndexPath:(NSIndexPath*)indexPath
.
.{
.
.[tableViewdeselectRowAtIndexPath:indexPathanimated:NO];
.
.XYZToDoItem*tappedItem=[self.toDoItemsobjectAtIndex:indexPath.row];
.
.tappedItem.completed=!tappedItem.completed;
.
.[tableViewreloadRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationNone];
.
.}
.
Checkpoint: 运行你的app。在loadInitialData中添加的项清单在你的表视图的表单元中可见。但是当你点击项时,没有发生任何事。为什么?
原因是内没有完成表视图单元显示完成状态的配置。你需要返回到tableView:cellForRowAtIndexPath方法并配置表单元在项目完成的时候显示一个指示。
通过一个方法来指示一个项目已经完成是在它后面安放一个复选标记。幸运的是,表视图单元有一个表单元附件在右侧。在默认的情况下,没有附件,然而你能够改变表单元来显示不同的附件,其中一级就是复选标记。所有你需要做的就是基于待办事宜项目的完成状态来设置表单元附件。
显示项目的完成状态
1.到 tableView:cellForRowAtIndexPath: 方法.
2.在设置表单元文本标签的后面添加如下方法:
.if(toDoItem.completed){
.
.cell.accessoryType=UITableViewCellAccessoryCheckmark;
.
.}else{
.
.cell.accessoryType=UITableViewCellAccessoryNone;
.
.}
3.
4.
你的 tableView:cellForRowAtIndexPath: 方法如下所示:
.-(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath
.
.{
.
.staticNSString*CellIdentifier=@"ListPrototypeCell";
.
.UITableViewCell*cell=[tableViewdequeueReusableCellWithIdentifier:CellIdentifierforIndexPath:indexPath];
.
.XYZToDoItem*toDoItem=[self.toDoItemsobjectAtIndex:indexPath.row];
.
.cell.textLabel.text=toDoItem.itemName;
.
.if(toDoItem.completed){
.
.cell.accessoryType=UITableViewCellAccessoryCheckmark;
.
.}else{
.
.cell.accessoryType=UITableViewCellAccessoryNone;
.
.}
.
.returncell;
.
.}
.
Checkpoint: 运行你的app。表视图的表单元显示你在loadInitialData中添加的项目清单。当你点击项时,一个复选框将在它后面出现。如果你在同一项点击,那么复选框消失。
Add New Items
添加新项目
创建待办事宜清单应用程序的最后一个步骤是实现添加事项的能力。当用户在XYZAddToDoItemViewController场景中的文本字段里输入一个项目的名字并点击Done按钮,你希望视图控制器能够创建一个新的表项目并且把它传递到XYZToDoListViewController在待办事宜清单中显示。
首先,你需要有一个清单项来配置。就像表视图一样,视图控制器是连接界面和模型的逻辑位置。给XYZAddToDoItemViewController一个属性来保存新添加的待办事宜项。
添加XYZToDoItem到XYZAddToDoItemViewController类
1.在工程导航器中,选择XYZAddToDoItemViewController.h.
因为你稍后将需要从表视图控制器访问这个清单项,所以让它成为公有属性非常重要。通过这种方式,你在接口文件中声明它。
2.在 @interface 行前面添加XYZToDoItem类的声明。
.#import "XYZToDoItem.h"
3.
4.
5.添加toDoItem属性到接口文件。
.@interfaceXYZAddToDoItemViewController : UIViewController
.
.
.
.@propertyXYZToDoItem*toDoItem;
.
.
.
.@end
6.
7.
为了取得新项的名字,视图控制器需要访问用户在文本字段中输入的名字的内容。为了做到这点,从XYZAddToDoItemViewController类中创建一个连接,连接到你的故事板中的文本字段。
连接文本字段到你的视图控制器
1.在大纲视图选择XYZAddToDoItemViewController 对象.
2.点击在窗口工具栏右上角的助理按钮,打开助理编辑器。
这个编辑器的右边将出现XYZAddToDoItemViewController.m。如果它没有显示,点击右侧的编辑器里面的文件名并选择XYZAddToDoItemViewController.m。
助理编辑器允许你有两个文件同时显示,使它可以执行在两个文件之间的操作——例如,将一个源文件中的对象拖到你的界面。
3.在你的故事板中选择文本字段。
4.从画布中拖拽文本字段到右侧的代码显示的编辑器,在XYZAddToDoItemViewController.m中的@interface行下面释放拖拽。
5.I再出现的对话框中,Name字段,键入textField.
剩下的选项不变。你的对话框看上去如下所示:
6.点击 Connect.
Xcode添加必要的代码到XYZAddToDoItemViewController.m来储存文本字段的点,并配置故事板来建立连接。
另外,你需要知道何时创建项目。你想创建项目只有在Done按钮被按下的时候。为了做到这点,要添加Done按钮的出口。
连接Done按钮到你的视图控制器
1.在故事板中,打开助理编辑器,并设置右侧的窗口为XYZAddToDoItemViewController.m.
2.在故事板中选择Done按钮。
3.从画布中按钮Control并拖拽Done按钮到编辑器的右侧,在XYZAddToDoItemViewController.m中的textField属性下面释放拖拽。
4.在出现的对话框中,Name字段,键入doneButton。
剩下的选项不变。你的对话框如下所示。
5.点击 Connect.
你现在有了一个方法来识别Done按钮。因为你想当Done按钮被按下的时候创建一个项,你需要知道什么时候发生。
当用户按下Done按钮,它开始一个unwind segue返回到待办事宜清单——你在第二个教程中创建的界面。在segue执行之前,系统给这个视图控制器相关的选择来通过调用prepareForSegue:来准备。正是这一点,你想要检查是否用户按下了Done按钮,如果按下了,创建一个新的待办事宜项。你能检查哪一个按钮被按下,如果是Done按钮,则常见项目。
在按下Done按钮后创建一个项
1.在工程导航器中选择 XYZAddToDoItemViewController.m。
2.在 @implementation 行后面添加 prepareForSegue:方法。
.-(void)prepareForSegue:(UIStoryboardSegue*)seguesender:(id)sender
.
.{
.
.}
3.
4.
5.在方法中,看Done按钮是否被按下。
如果没有,你希望方法返回但不做任何事情。
.if(sender!=self.doneButton)return;
6.
7.
8.看文本字段是否有文本。
.if(self.textField.text.length>0){
.
.}
9.
10.
11.如果有文本,创建一个新的项目,把它的名字命名为文本字段中的文本。同时,要确保完成状态设置为NO。
.self.toDoItem=[[XYZToDoItemalloc]init];
.
.self.toDoItem.itemName=self.textField.text;
.
.self.toDoItem.completed=NO;
12.
13.
如果没有字段,你不希望它保存项,所以你不做任何事情。
你的 prepareForSegue: 方法如下所示:
.-(void)prepareForSegue:(UIStoryboardSegue*)seguesender:(id)sender
.
.{
.
.if(sender!=self.doneButton)return;
.
.if(self.textField.text.length>0){
.
.self.toDoItem=[[XYZToDoItemalloc]init];
.
.self.toDoItem.itemName=self.textField.text;
.
.self.toDoItem.completed=NO;
.
.}
.
.}
.
你已经创建了一个新项,你需要把它传递到XYZToDoListViewController,这样它能被加到待办事宜清单中。为了实现这一点,你需要重新审视你在第二个教程中写的unwindToList:方法。当XYZAddToDoItemViewController场景关闭的时候,这个方法被回调,当用户按下Cancel或Done按钮时这种情况发生。
unwindToList方法把segue座位参数,就像所有的方法使用unwind segue作为目标一样。这个segue参数是从XYZAddToDoItemViewController返回到XYZToDoListViewController的segue。因为一个segue是两个视图控制器之间的转换,它知道他的源视图控制器——XYZAddToDoItemViewController。通过项它的源视图控制器请求segue对象,你能在unwindToList:方法中访问任何在源视图控制器中存储的数据。如果是nil,这个项目永远不会被创建——文本字段没有文本或者Cancel按钮被按下。如果有一个值,你检索这个项目,添加它到你的toDoItems数组,并且通过重新加载表视图中的数据来显示在待办事宜清单中。
储存和显示新的项
1.在工程视图中选择XYZToDoListViewController.m.
2.在 XYZAddToDoItemViewController 类上面@interface行之前添加一个import声明。
.#import "XYZAddToDoItemViewController.h"
3.
4.
5.在第二个教程你所添加的方法中找到 unwindToList:方法。
6.在这个方法中,检索源视图控制器——你从XYZAddToDoItemViewController返回到的控制器
.XYZAddToDoItemViewController*source=[seguesourceViewController];
7.
8.
9.检索控制器的待办事宜项。
.XYZToDoItem*item=source.toDoItem;
10.
11.
当Done按钮被按下后,这个项被创建。
12.看这个项是否存在。
.if(item!=nil){
.
.}
13.
14.
If it does exist, add the item to your toDoItems array. 如果存在,把项加入toDoItems数组。
.[self.toDoItemsaddObject:item];
15.
16.
17.重新加载你的表的数据。
因为表视图不能跟踪数据,数据是数据源来负责的——这个地方,你的视图控制器——来通知表视图有新数据。
.[self.tableViewreloadData];
18.
19.
你的 unwindToList: 方法如下所示:
.-(IBAction)unwindToList:(UIStoryboardSegue*)segue
.
.{
.
.XYZAddToDoItemViewController*source=[seguesourceViewController];
.
.XYZToDoItem*item=source.toDoItem;
.
.if(item!=nil){
.
.[self.toDoItemsaddObject:item];
.
.[self.tableViewreloadData];
.
.}
.
.}
.
Checkpoint:运行app。现在你点击(+)并创建一个新项,你应该可以在你的待办事宜清单中看见。恭喜你,你已经创建了一个根据用户输入、储存到对象、并在两个视图控制器中传递对象的app。这是以故事板为基础在两个场景中移动数据的app。
Recap
回顾
你几乎完成了这篇关于开发iOS app的介绍性文章。在最后的部分给你更多关于如何在这个文档中找到你想要的内容的信息,以及提出了下一步你如何学习关于创建更高级app的建议。
Writing a Custom Class
iOS Technologies
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。