iOS Programming Editing UITableView
iOS Programming Editing UITableView
1.1 Editing mode
UITableView has an editing property, and when this property is set to YES, the UITableView enters editing mode.
UITableVIew有一个editing property,当属性设置为YES时,UITableView设置为editing mode。
Depending on how the table view is configured, the user can change the order of the rows, add rows, or remove rows. Editing mode does not allow the user to edit the content of a row.
根据tableview 如何配置,用户可以改变row的order,添加row,移除row,但是编辑模式却不能允许增加行。
That the table view uses the word "header" in two different ways: There can be a table header and there can be section headers. Likewise, there can be a table footer and section footers.
table view 有table header 和section header。类似的也有table footer 和section footer。
Notice that headerView is a strong property. This is because it will be a top-level object in the XIB file; you use weak references for objects that are owned (directly or indirectly) by the top-level objects。
注意到你使用了strong 属性。那是因为headerView 将是xib文件的最上层。我们使用弱引用指向属于最上层的对象。
XIB files are typically used to create the view for a view controller, but they can also be used any time you want to lay out view objects, archive them, and have them loaded at runtime.
xib文件一般用来为view controller 创建新的view。但是他们也可以用在任何你像lay out view object,获取他们,在运行时得到他们。
step 1
Create a new file (Command-N). From the iOS section, select User Interface, choose the Empty template, and click Next
Drag a UIView onto the canvas. Then drag two instances of UIButton onto that view. You will then want to resize the UIView so that it just fits the buttons; however, Xcode will not let you: the size is locked. To unlock the size, select the UIView on the canvas and open the attributes inspector. Under the Simulated Metrics section, select None for the Size option.
To load a XIB file manually, you use NSBundle.
为了手动加载XIB 文件,你需要NSBundle。
This class is the interface between an application and the application bundle it lives in.
这个类是application和application bundle 的接口。
When you want to access a file in the application bundle, you ask NSBundle for it.
当你需要从application bundle 中获取一个文件时,需要从NSBundle中获取。
An instance of NSBundle is created when your application launches, and you can get a pointer to this instance by sending the message mainBundle to NSBundle.
一个NSBundle的实例在应用启动的时候就已经创建了。你可以通过发送一个消息mainBundle 给NSBundle 获取一个指向它的指针。
Once you have a pointer to the main bundle object, you can ask it to load a XIB file.
一旦你获取了指向main bundle 的指针,你就可以要求它加载一个XIB文件了。
Notice that this is a getter method that does more than just get.
注意这个getter方法又不仅仅是一个get方法。
This is a common pattern: Lazy Instantiation puts off creating the object until it is actually needed.
这是一个常用的模式:延迟实例化,只有当它确实需要的时候才实例化该对象。
In some cases this approach can significantly lower the normal memory footprint of your app.
在一些情况下这确实能降低你的内存。
- (UIView *)headerView
{
// If you have not loaded the headerView yet... if (!_headerView) {
// Load HeaderView.xib
}
[[NSBundle mainBundle] loadNibNamed:@"HeaderView" owner:self
options:nil];
return _headerView; }
notice that you passed self as the owner of the XIB file. This ensures that when the main NSBundle is parsing the resultant NIB file at runtime, any connections to the File's Owner placeholder will be made to that BNRItemsViewController instance.
你也注意到传递self 给xib 文件的owner。这确保了当main NSBundle 解析NIB文件的结果时,任何连接到FIle's owner placeholder的都将在BNRItemsViewController 实例。
UIView *view=self.headerView;
[self.tableView setTableHeaderView:view];
In addition, any object can load a XIB file manually by sending the message loadNibNamed:owner:options: to the application bundle.
任何想加载xib 文件的对象可以发送一个loadNibNamed:owner:options:给application bundle。
UIViewController's default XIB loading behavior uses the same code.
The only difference is that it connects its view outlet to the view object in the XIB file.
唯一不同的区别是它在XIB 文件里 连接view outlet 到view object .
Imagine what the default implementation of loadView for UIViewController probably looks like:
- (void)loadView
{
// Which bundle is the NIB in?
// Was a bundle passed to initWithNibName:bundle:?
NSBundle *bundle = [self nibBundle]; if (!bundle) {
// Use the default
bundle = [NSBundle mainBundle]; }
// What is the NIB named?
// Was a name passed to initWithNibName:bundle:? NSString *nibName = [self nibName];
if (!nibName) {
// Use the default
nibName = NSStringFromClass([self class]); }
// Try to find the NIB in the bundle
NSString *nibPath = [bundle pathForResource:nibName
ofType:@"nib"];
// Does it exist? if (nibPath) {
// Load it (this will set the view outlet as a side-effect
[bundle loadNibNamed:nibName owner:self options:nil]; } else {
// If there is no NIB, just create a blank UIView
self.view = [[UIView alloc] init]; }
}
1.1.2 Now let's implement the toggleEditingMode: method.
现在实现 toogleEditingMode方法。
You could toggle the editing property of UITableView directly.
你可以直接改变UITableView 的 editing property 。
However, UITableViewController also has an editing property.
然而UITableViewController仍然有一个editing property。
A UITableViewController instance automatically sets the editing property of its table view to match its own editing property.
UITableViewController 实例自动设置table view 的editing property 属性来匹配自己的属性。
To set the editing property for a view controller, you send it the message setEditing:animated:
为了设置view controller 的editing property ,你给它发送一个setEditing:animated的消息。
- (IBAction)toggleEditingMode:(id)sender
{
// If you are currently in editing mode... if (self.isEditing) {
// Change text of button to inform user of state
[sender setTitle:@"Edit" forState:UIControlStateNormal];
// Turn off editing mode
[self setEditing:NO animated:YES]; } else {
// Change text of button to inform user of state
[sender setTitle:@"Done" forState:UIControlStateNormal];
// Enter editing mode
[self setEditing:YES animated:YES]; }
}
1.2 Adding rows
There are two common interfaces for adding rows to a table view at runtime.
(1)A button above the cells of the table view.
table view 的cell 上的button。
This is usually for adding a record for which there is a detail view.
为了给一个记录添加一些细节。
For example, in the Contacts app, you tap a button when you meet a new person and want to take down all their information.
例如,在联系人app中,你点击一个button当你遇见一个新的人并想记录所有它的信息。
(2)A cell with a green plus sign.
一个有绿色加号的cell。
This is usually for adding a new field to a record, such as when you want to add a birthday to a person's record in the Contacts app.
Ultimately, it is the dataSource of the UITableView that determines the number of rows the table view should display.
最终是UITableView的datasource 决定了到底有多少行要显示。
After inserting a new row, the table view has six rows (the original five plus the new one).
table view添加一行后就变成了六行。
Then, it runs back to its dataSource and asks it for the number of rows it should be displaying.
然后就去datasource 需找它到底需要显示多少行。
BNRItemsViewController consults the store and returns that there should be five rows. The UITableView then says, "Hey, that is not right!" and throws an exception.
就会返回给UITableView说是有5行。这时就产生了不对了。UITableView就说不对啊。 就抛出了异常。
You must make sure that the UITableView and its dataSource agree on the number of rows.
你必须要保证UITableView和datasource保持一致的行数。
Thus, you must add a new BNRItem to the BNRItemStore before you insert the new row.
因此你要在UITableView添加新行前就把新的BNRItem添加到BNRItemStore。
-(IBAction)addNewItem:(id)sender{
BNRItem *newItem=[[BNRItemStore sharedStore] createItem];
NSInteger lastRow=[[[BNRItemStore sharedStore] allItems]indexOfObject:newItem];
NSIndexPath *indexpath=[NSIndexPath indexPathForRow:lastRow inSection:0];
[self.tableView insertRowsAtIndexPaths:@[indexpath] withRowAnimation:UITableViewRowAnimationTop];
}
1.3 Deleting Rows
1.3.1
Before the table view will delete a row, it sends its data source a message about the proposed deletion and waits for a confirmation message before pulling the trigger.
在table view删除一行之前,它发送给data source 一个信息关于删除的提议并等待确认的消息。
When deleting a cell, you must do two things: remove the row from the UITableView and remove the BNRItem associated with it from the BNRItemStore.
当删除一个cell时,你必须做两件事情:从UITableView中移除row(2)从BNRItemStore中把BNRItem移除。
- (void)removeItem:(BNRItem *)item;
- (void)removeItem:(BNRItem *)item
{
[self.privateItems removeObjectIdenticalTo:item];
}
1.3.2 removeObject VS removeObjectIdenticalTo
removeObject: goes to each object in the array and sends it the message isEqual:. A class can implement this method to return YES or NO based on its own determination. For example, two BNRItem objects could be considered equal if they had the same valueInDollars.
removeObject: 进入列逐个对象进行比较。发送isEqual消息。一个类能实现这个方法并返回yes or no 。
The method removeObjectIdenticalTo:, on the other hand, removes an object if and only if it is the exact same object as the one passed in this message.
removeObjectIdenticalTo当且仅当 它与给定的对象完全相同时才删除该对象。
1.3.3
you will implement tableView:commitEditingStyle:forRowAtIndexPath:, a method from the UITableViewDataSource protocol.
(This message is sent to the BNRItemsViewController. Keep in mind that while the BNRItemStore is the where the data is kept, the BNRItemsViewController is the table view's dataSource.)
这个消息被送给BNRItemsViewController。记住当BNRItemStore是data 保持的地方,BNRItemsViewController是table view 的datasource。
When tableView:commitEditingStyle:forRowAtIndexPath: is sent to the data source, two extra arguments are passed along with it. The first is the UITableViewCellEditingStyle, which, in this case, is UITableViewCellEditingStyleDelete. The other argument is the NSIndexPath of the row in the table.
当tableView:commitEditingStyle:forRowAtIndexPath被发送到data source 时,两个额外的参数也随着一起传递过来了。第一个是UITableViewCellEditingStyle,在这个情况下是UITableViewCellEditingStyleDelete,第二个是table 的行的NSIndexPath。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
// If the table view is asking to commit a delete command... if (editingStyle == UITableViewCellEditingStyleDelete) {
NSArray *items = [[BNRItemStore sharedStore] allItems]; BNRItem *item = items[indexPath.row];
[[BNRItemStore sharedStore] removeItem:item];
// Also remove that row from the table view with an animation [tableView deleteRowsAtIndexPaths:@[indexPath]
} }
1.4 Moving Rows
Moving a row, however, does not require confirmation; the table view moves the row on its own authority and reports the move to its the data source by sending the message tableView:moveRowAtIndexPath:toIndexPath:.
移动一行,不需要确认。table view 在自己的领域内移动行,通过发送tableView:moveRowAtIndexPath:toIndexPath告诉这个移动给data source 。
But before you can implement the data source method, you need to give the BNRItemStore a method to change the order of items in its allItems array.
但在实现datasource方法之前,你应该给BNRItemStore一个方法让他该百年items在allItems 的顺序。
In BNRItemStore.h, declare this method.
- (void)moveItemAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex;
In BNRItemStore.m, implement moveItemAtIndex:toIndex:.
- (void)moveItemAtIndex:(NSUInteger)fromIndex
toIndex:(NSUInteger)toIndex
{
if (fromIndex == toIndex) {
return; }
// Get pointer to object being moved so you can re-insert it BNRItem *item = self.privateItems[fromIndex];
// Remove item from array
[self.privateItems removeObjectAtIndex:fromIndex];
// Insert item in array at new location
[self.privateItems insertObject:item atIndex:toIndex]; }
In BNRItemsViewController.m, implement tableView:moveRowAtIndexPath:toIndexPath: to update the store.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toIndexPath:(NSIndexPath *)destinationIndexPath {
[[BNRItemStore sharedStore] moveItemAtIndex:sourceIndexPath.row toIndex:destinationIndexPath.row];
}
The UITableView can ask its data source at runtime whether it implements tableView:moveRowAtIndexPath:toIndexPath:. If it does, the table view says, "Good, you can handle moving rows. I'll add the re-ordering controls." If not, it says, "If you aren't implementing that method, then I won't put controls there."
UITableView 将询问它的data source 是佛实现了tableView:moveRowAtIndexPath:toIndexPath。如果实现了,那么tableview 将会说"好啊,你能处理这个移动的行,我将添加重新排序控制",如果没有,"你没有实现这个方法,我不能实现这个控制。"
iOS Programming Editing UITableView的更多相关文章
- iOS programming UITableView and UITableViewController
iOS programming UITableView and UITableViewController A UITableView displays a single column of dat ...
- iOS Programming UIStoryboard 故事板
iOS Programming UIStoryboard In this chapter, you will use a storyboard instead. Storyboards are a f ...
- iOS Programming State Restoration 状态存储
iOS Programming State Restoration 状态存储 If iOS ever needs more memory and your application is in the ...
- iOS Programming UINavigationController
iOS Programming UINavigationController the Settings application has multiple related screens of info ...
- iOS开发系列--UITableView全面解析
--UIKit之UITableView 概述 在iOS开发中UITableView可以说是使用最广泛的控件,我们平时使用的软件中到处都可以看到它的影子,类似于微信.QQ.新浪微博等软件基本上随处都是U ...
- ios Programming:The Big Nerd Ranch Guid(6th Edition) (Joe Conway & AARON HILLEGASS 著)
Introduction (已看) Prerequisites What Has Changed in the Sixth Edition? Our Teaching Philosophy How t ...
- iOS Programming NSUserDefaults
iOS Programming NSUserDefaults When you start an app for the first time, it uses its factory settin ...
- iOS Programming UIWebView 2
iOS Programming UIWebView 1 Instances of UIWebView render web content. UIWebView可以显示web content. In ...
- iOS Programming Web Services and UIWebView
iOS Programming Web Services and UIWebView The work is divided into two parts. The first is connecti ...
随机推荐
- <转>bash: qmake: command not found...
昨天发现qmake这个命令不能使用,查了一些资料,大部分都说是环境变量没有设置好: Qt默认安装是在 /opt/qt-xxxx/qt/bin 或者 /opt/qt-xxx/bin 下.实在不行就查找 ...
- 邮件:事务失败。 服务器响应为:DT:SPM 163 smtp
几年前我做的一个项目,日发邮件最高峰时几十万.自以为对邮件发送方面已经有了一定认识,所以近期机缘巧合之下,又有项目需要发送邮件,不禁自信满满,暗自庆幸能不手到擒来乎? 不想老革命遇到新问题.我原先的邮 ...
- socket.io中文文档
socket.io 中文文档转载于:http://www.cnblogs.com/xiezhengcai/p/3956401.html 服务端 io.on(‘connection’,function( ...
- POJ1984 Navigation Nightmare —— 种类并查集
题目链接:http://poj.org/problem?id=1984 Navigation Nightmare Time Limit: 2000MS Memory Limit: 30000K T ...
- 大话SEO网站优化|SEO优化入门技术详解
网络营销 网络营销是借助一切被目标用户认可的网络应用服务平台开展的引导用户关注的行为或活动,目的是促进产品在线销售及扩大品牌影响力. web1.0时代有搜索引擎营销.BBS营销.邮件营销.病毒式营销. ...
- create database 默认utf-8
CREATE DATABASE IF NOT EXISTS dbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci; 这是sql语句 CREATE TA ...
- 并不对劲的bzoj5341:loj2553:uoj400:p4565:[Ctsc2018]暴力写挂
题目大意 有两棵\(n\)(\(n\leq366666\))个节点的树,\(T\)和\(T'\),有边权 \(dep(i)\)表示在\(T\)中\(i\)号点到\(1\)号点的距离,\(dep'(i) ...
- BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树
BZOJ_5343_[Ctsc2018]混合果汁_二分答案+主席树 题意:给出每个果汁的价格p,美味度d,最多能放的体积l.定义果汁混合后的美味度为果汁的美味度的最小值. m次询问,要求花费不大于g, ...
- 前端之html第一天
一.内容
- 深入学习 Block
本文翻译自苹果的文档,有删减,也有添加自己的理解部分. 如果有Block语法不懂的,可以参考fuckingblocksyntax,里面对于Block 为了方便对比,下面的代码我假设是写在ViewCon ...