2010-08-08 33 views
1

我有一個ItemAddViewController,它將自己呈現爲模態視圖。其中一個字段推送一個新的視圖控制器CategorySelectionViewController,它允許用戶選擇一個類別。保持視圖控制器之間的值

ItemAddViewController.h

@property (nonatomic, retain) Category *category; 

CategorySelectionViewController.h

@property (nonatomic, retain) Category *category; 

CategorySelectionViewController.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
NSManagedObject *currentCategory = category; 

if (currentCategory != nil) { 
    NSInteger index = [categories indexOfObject:currentCategory]; 
    NSIndexPath *selectionIndexPath = [NSIndexPath indexPathForRow:index inSection:0]; 
    UITableViewCell *checkedCell = [tableView cellForRowAtIndexPath:selectionIndexPath]; 
    checkedCell.accessoryType = UITableViewCellAccessoryNone; 
} 

//set the checkmark accessory 
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark]; 

//update the category 
category =[categories objectAtIndex:indexPath.row]; 
NSLog(@"%@", category); 
// Deselect row 
[tableView deselectRowAtIndexPath:indexPath animated:YES]; 

}

ItemAddViewCo ntroller.m

- (void)viewWillAppear:(BOOL)animated { 
    NSLog(@"%@", category); 
} 

類別在CategorySelectionViewController創建上設置。當在類別選擇屏幕上選擇類別時,NSLog報告正確的對象。當它返回到ItemAddViewController時,它再次爲空。這兩個應該是同一個對象,所以我不確定我做錯了什麼。

基本上,我需要一個很好的方法來在兩個視圖控制器之間傳遞數據。

回答

0

UIViewController類的parentViewController方法應該給你一個指向視圖控制器的指針,該視圖控制器「管理」當前視圖控制器。一旦你知道了,你可以在其上設置category屬性。

這就是說,我並沒有在iOS上對視圖控制器做過很多工作,但我不確定「什麼parentViewController應該指向給定視圖」的語義是......但我會冒險說您的ItemAddViewController實例可能應該是您的CategorySelectionViewController的父項。

這裏有一個如何做到這一點的例子:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSManagedObject *currentCategory = category; 

    if (currentCategory != nil) { 
     NSInteger index = [categories indexOfObject:currentCategory]; 
     NSIndexPath *selectionIndexPath = [NSIndexPath indexPathForRow:index inSection:0]; 
     UITableViewCell *checkedCell = [tableView cellForRowAtIndexPath:selectionIndexPath]; 
     checkedCell.accessoryType = UITableViewCellAccessoryNone; 
    } 

    //set the checkmark accessory 
    [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark]; 

    //update the category 
    [self parentViewController].category = [categories objectAtIndex:indexPath.row]; 
    NSLog(@"%@", category); 
    // Deselect row 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

編輯:文檔說本作的parentViewController方法:

父視圖控制器有導航相關,標籤欄,和模態視圖控制器層次結構。在這些層級中的每一箇中,父級是負責顯示當前視圖控制器的的對象。

我認爲這意味着該parentViewController您模式視圖的控制點,任何視圖控制器接收到的消息presentModalViewController:animated:

+0

非常好的答案。 – 2010-08-08 06:25:45

+0

有趣。但是,看起來父視圖控制器是導航控制器,而不是ItemAddViewController(並且導航控制器的父級是標籤欄控制器) – DVG 2010-08-08 18:11:15

0

@David's是一個很好的答案,但這將保持數據在parentViewController。如果您希望數據對於ItemAddViewController(子控制器)是本地的,那麼您可以在第二個視圖中創建本地iVar,並在顯示它或將其推送到導航控制器之前爲其分配一個值。 See my answer to a previous SO question here看看它是如何完成的。

1

要跟進什麼已經說過,一種方法通常採取類似的問題是使ItemViewController(父)CategorySelectionViewController(孩子)的代表,以及當tableView:didSelectRowAtIndexPath:大火在CategorySelectionViewController,將消息發送到委託在ItemAddViewController中回調 - 傳入所選類別作爲參數。

這種理念可以實現類似以下內容:

@protocol CategorySelectionViewControllerDelegate; 

// in CategorySelectionViewController.h 
@interface CategorySelectionViewController : UITableViewController { 
    id<CategorySelectionViewControllerDelegate> delegate; 
} 
@property (nonatomic, assign) id<CategorySelectionViewControllerDelegate> delegate; 
@end 

@protocol CategorySelectionViewControllerDelegate 
// delegate callback skeleton 
-(void)userDidSelectCategory:(Category *)categorySelected; 
@end 

// in CategorySelectionViewController.m 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSManagedObject *currentCategory = category; 

    if (currentCategory != nil) { 
     NSInteger index = [categories indexOfObject:currentCategory]; 
     NSIndexPath *selectionIndexPath = [NSIndexPath indexPathForRow:index inSection:0]; 
     UITableViewCell *checkedCell = [tableView cellForRowAtIndexPath:selectionIndexPath]; 
     checkedCell.accessoryType = UITableViewCellAccessoryNone; 
    } 

    //set the checkmark accessory 
    [[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark]; 

    // here's where you message the delegate callback 
    [self.delegate userDidSelectCategory:[categories objectAtIndex:indexPath.row]]; 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

然後ItemAddViewController的骨架將進行修改,以符合CategorySelectionViewControllerDelegate協議:

// in ItemAddViewController.h 
@protocol CategorySelectionViewControllerDelegate; 
@interface ItemAddViewController : UITableViewController <CategorySelectionViewControllerDelegate> 
{ /* etc.... */ } 
@property (nonatomic, retain) Category *category; 
// delegate callback 
-(void)userDidSelectCategory:(Category *)categorySelected 

// in ItemAddViewController.m 
// set the CategorySelectionViewController delegate as this ItemViewController when you instantiate it 
-(void)showCategorySelectionViewController { 
    CategorySelectionViewController *myChild = [[CategorySelectionViewController alloc] init]; 
    myChild.delegate = self; 
    [self presentModalViewController:myChild animated:YES]; 
} 
// implement the delegate callback 
-(void)userDidSelectCateogry:(Category *)categorySelected { 
    self.category = categorySelected; 
    // other handling code as needed... 
} 

至於這樣做致電[self parentViewController]CategorySelectionViewController,趕上是ItemAddViewController繼承自UITableView,所以當你發送消息[self parentViewController]時,編譯器認爲你正在與UITableView,而不是ItemAddViewController,除非您明確強制轉換。因此,它不知道self.parentViewController有一個名爲category的屬性。您可以通過添加類型演員來解決此問題:

ItemAddViewController *itemAddViewControllerParent = (ItemAddViewController *)[self parentViewController]; 
itemAddViewControllerParent.category = [categories objectAtIndex:indexPath.row]; 

希望這有助於。

相關問題