2012-01-11 38 views
3

我的目標是在每次更改某些配置時通知UITableView自行刷新。問題在於配置視圖在產生信號的相同視圖上「不」。 (是的,我使用了選項卡式應用程序。)將「重新加載」信號從一個視圖發送到另一個視圖的最佳做法

當前我在AppDelegate中使用一種全局變量來檢測一個視圖中的更改,並在另一個視圖中執行檢查。這很好,但代碼不可讀,因爲它緊密耦合。有沒有一個優雅的方法來做到這一點?我在這個編程框架中錯過了什麼嗎?

如果有這樣一種優雅的方式,我想UITableView的刷新過程應該在通知發生後立即發生。在這種情況下,我想知道是否有可能延遲UITableView刷新自身,直到出現viewDidAppear。

+0

怎麼樣[通知](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Notifications/Introduction/introNotifications.html#//apple_ref/doc/uid/10000043i )? – 2012-01-11 16:21:14

回答

2

我會用志願(鍵值觀察),以保持它的變化時跟蹤:

- (void)viewDidLoad { 
     [super viewDidLoad]; 

     // Note that you can use the options to get the new value passed when it 
     // changes if you want to update immediately. 
     [configurationObject addObserver:self forKeyPath:@"configurationItem" options:0 context:nil]; 
} 

- (void)viewDidUnload { 
     [super viewDidUnload]; 
     [configurationObject removeObserver:self forKeyPath:@"configurationItem"]; 
} 

// Note that I would refresh in viewWillAppear instead of viewDidAppear 
- (void)viewWillAppear:(BOOL)animated { 
     [super viewWillAppear:animated]; 
     if (self.needToRefreshData == YES) { 
      [self.tableView refreshData]; 
     } 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
     if (keyPath isEqualToString:@"configurationItem") { 
      [self.needToRefreshData = YES]; 
     } 
} 
+0

如果你這樣做,它會一直更新,不管底層數據如何改變,當你想改變它時你不必做任何特別的事情(比如記得刷新其他對象!) – lnafziger 2012-01-12 21:58:06

1

那麼,一種方法是有一些常見的類(單例可能是哪種應用程序委託類型),它跟蹤您的模型,當viewController檢測到更改時它可以將模型標記爲已更改,然後有問題的視圖進入查看,即viewDidAppear被調用,它可以查詢模型,看看是否已更改標誌已設置,如果它已然後你知道重新加載表視圖,否則你不...

另一種方式可以是使用通知中心,如果你的視圖被加載了,它可以註冊模型更改的通知,在這個通知中,它設置了一個標誌,在下次它出現時它需要重新加載表視圖屏幕..

希望這有助於

1

您可以將配置存儲在覈心數據中,並使用NSFetchedResultsController並將相關視圖控制器設置爲委託。這樣,只要數據發生變化,您的視圖控制器就會得到回調。

蘋果有一些boilerplate code處理更新以及

2

使用委託設計模式,從傳遞數據一個視圖控制器到另一個。

例如,假設一個選項卡顯示UITableViewController中的汽車列表,並且您有另一個視圖讓用戶將新車添加到列表中。你可以讓的UITableViewController

  • 採用AddCarViewController的協議
  • 爲自己設定的委託AddCarViewController的協議
  • 履行其協議方法
  • 執行協議的方式通知

然後,您可以讓AddCarViewController

  • 創建協議
  • 與獲取和設置方法
  • 申報對象引用代表
  • 定義一個協議
  • 告知代表當進行下次動作

在以下看看下的方法您的UITableViewController的示例代碼

@interface ViewController : UITableViewController <AddCarViewControllerDelegate> 

      : 
      : 

// The addCar: method is invoked when the user taps the Add button created at run time. 
- (void)addCar:(id)sender 
{ 
// Perform the segue named ShowAddCar 
[self performSegueWithIdentifier:@"ShowAddCar" sender:self]; 
} 

      : 
      : 

// This method is called by the system whenever you invoke the method  performSegueWithIdentifier:sender: 
// You never call this method. It is invoked by the system. 
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    NSString *segueIdentifier = [segue identifier]; 

    if ([segueIdentifier isEqualToString:@"ShowAddCar"]) { 

     // Obtain the object reference of the destination view controller 
     AddCarViewController *addCarViewController = [segue destinationViewController]; 

     // Under the Delegation Design Pattern, set the addCarViewController's delegate to be self 
     addCarViewController.delegate = self; 

     // Instantiate a Save button to invoke the save: method when tapped 
     UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] 
             initWithBarButtonSystemItem:UIBarButtonSystemItemSave 
             target:addCarViewController action:@selector(save:)]; 

     // Set up the Save custom button on the right of the navigation bar 
     addCarViewController.navigationItem.rightBarButtonItem = saveButton; 

    } 

} 

       : 
       : 


- (void)addCarViewController:(AddCarViewController *)controller didFinishWithSave: (BOOL)save { 
       : 
       : 
} 

AddCarViewController的示例代碼在這裏

@protocol AddCarViewControllerDelegate; 

@interface AddCarViewController : UIViewController 

@property (nonatomic, strong) IBOutlet UITextField *carMake; 
@property (nonatomic, strong) IBOutlet UITextField *CarName; 
@property (nonatomic, assign) id <AddCarViewControllerDelegate> delegate; 

// The keyboardDone: method is invoked when the user taps Done on the keyboard 
- (IBAction)keyboardDone:(id)sender; 

// The save: method is invoked when the user taps the Save button created at run time. 
- (void)save:(id)sender; 

@end 

/* 
The Protocol must be specified after the Interface specification is ended. 
Guidelines: 
- Create a protocol name as ClassNameDelegate as we did above. 
- Create a protocol method name starting with the name of the class defining the protocol. 
- Make the first method parameter to be the object reference of the caller as we did below. 
*/ 
@protocol AddCarViewControllerDelegate 
- (void)addCarViewController:(AddCarViewController *)controller didFinishWithSave:(BOOL)save; 
@end 
+0

by方式,這裏的代碼是iOS5。請注意,我正在使用performsegue API。以前的SDK可以採用其他的一切 – 2012-01-11 16:59:00

+0

+1此方法似乎比KVO更優雅(即不需要檢查self.needToRefreshData == YES),但在我看來,編碼更復雜。 – 2012-01-12 22:54:57

+1

Killua:self.needToRefreshData的檢查是來自他的請求,因爲他只希望它在視圖要顯示時更新。使用KVO,您可以輕鬆進行即時更新(甚至可以在不檢查底層數據的情況下執行更新,因爲您可以將它作爲參數傳遞給observeValueForKeypath。 – lnafziger 2012-01-13 04:18:16

相關問題