iOS Programming Editing UITableView,editinguitableview

來源:互聯網
上載者:User

iOS Programming Editing UITableView,editinguitableview

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 將會說"好啊,你能處理這個移動的行,我將添加重新排序控制",如果沒有,"你沒有實現這個方法,我不能實現這個控制。"

 

 

 

 

 

 

 

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.