3

使用情节提要我目前有一个静态的 Uitableview。当用户从父表视图中选择一行时,将显示一个新的表视图,其中显示一些选项。一旦用户从新的表格视图中选择了一行,我想关闭表格并显示父视图控制器并在单元格中显示用户选择。几乎是表单的收音机选择。

我是否处理视图控制器的关闭以及视图中数据的传递将出现还是在索引路径处选择行?我被困了一段时间。

4

3 回答 3

9

使用委托。子视图控制器定义了父视图控制器实现的委托协议。在父视图控制器显示子视图控制器之前,它会将自己设置为子视图控制器的委托。当用户在子视图中选择了一行或任何内容时,子视图控制器在其委托上调用一个方法并关闭自己。


我为你写了一个示例代码:https ://github.com/vikingosegundo/StateSelection

父视图控制器是 MasterViewController。
子视图控制器是 StateSelectionViewController。

  • StateSelectionViewController 在其标头中定义了一个协议:StateSelectionDelegate并具有一个委托属性id<StateSelectionDelegate> delegate

    @protocol StateSelectionDelegate <NSObject>
    -(void) selectedState:(NSString *)state forNation:(NSString *)nation;
    @end  
    
  • MasterViewController 符合这个协议,它实现了唯一的委托方法selectedState:forNation:

    -(void)selectedState:(NSString *)state forNation:(NSString *)nation
    {
        self.statesDictionray[nation] = state;
        [self.tableView reloadData];
    }
    
  • 在 MasterViewController 期间prepareForSegue:,它为自己设置了一个目标视图控制器的委托,它恰好是 StateSelectionViewController。

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([[segue identifier] isEqualToString:@"showDetail"]) {
            NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
            NSString *selectedNation =[[[self.tableView cellForRowAtIndexPath:indexPath] textLabel] text];
            [[segue destinationViewController] setSelectedNation:selectedNation];
            [[segue destinationViewController] setDelegate:self];
        }
    }
    
  • 现在执行 segue 并显示 StateSelectionViewController 的 tableview。

  • 一旦用户在其中一行上的选项卡上,StateSelectionViewController 将调用

    [self.delegate selectedState: <theState> forNation: <theNation>];
    

    并解雇或弹出自己。请注意用于确定控制器呈现方式的开关。

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
           [self.delegate selectedState:stateDictionary[_selectedNation][indexPath.row] forNation:_selectedNation];
           if(self.presentingViewController)
               [self dismissViewControllerAnimated:NO completion:NULL];
           else
               [self.navigationController popViewControllerAnimated:YES];
    
    }
    
于 2013-09-25T17:09:57.280 回答
5

在我的另一个答案旁边,我想展示另一种我直到几分钟前才意识到的方式:使用展开的转场而不是委托。

展开的转场将如何逆转将我们带到视图控制器的转场。“Some how” 意味着您实际上不需要返回上一个控制器,而是返回上一个控制器。创建展开转场时,您将其与签名的目标连接

-(IBAction)actionName:(UIStoryboardSegue *)segue

在以前的视图控制器之一中。有关详细信息,请参见此处:使用 Xcode Storyboard
调用该操作的 segue 将包含源控制器,在我们的示例中为详细视图控制器。我们现在可以访问我们在其上定义的属性或方法。

@interface StateSelctionViewController : UITableViewController
@property (nonatomic, strong) NSString *selectedNation;
@property (nonatomic, strong, readonly) NSString *selectedState;
@end

我将 selectedState 设为只读,因此很明显不能设置,但应在选择后读取。我在类扩展中重新声明它为读写。

@interface StateSelctionViewController ()
@property (nonatomic, strong, readwrite) NSString *selectedState;
@end

在情节提要中,我创建了一个手动展开转场,如技术说明 TN2298 所示:图 2
选择一行后,我将设置selectedState并执行展开转场

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    self.selectedState =  stateDictionary[_selectedNation][indexPath.row];
    [self performSegueWithIdentifier:@"unwind" sender:self];
}

这将在主视图控制器中执行连接的操作

-(void)returned:(UIStoryboardSegue *)sender
{
    NSLog(@"%@", NSStringFromSelector(_cmd));
    [self.statesDictionray setObject:[sender.sourceViewController selectedState]
                              forKey:[sender.sourceViewController selectedNation]];
    [self.tableView reloadData];
}

我创建了一个示例代码:https ://github.com/vikingosegundo/StateSelectionUnwind

于 2013-09-26T04:20:46.047 回答
1

要扩展 Vikingosegundo 的建议:

当您的第一个视图控制器连接到您的第二个视图控制器时,请实现 prepareForSegue 方法。

给你的第二个视图控制器一个委托属性,它符合 parentVC 协议。

在您的 parentVC 协议中定义方法,让您通知委托有关当前选定的表格视图单元格。

在您的第一个视图控制器的 prepareForSegue 方法中,将您自己设置为第二个视图控制器的委托。

当用户更改第二个视图控制器中的单元格时,使用委托属性通知父视图控制器。

我在 github 上有一个示例应用程序,它说明了这个确切的设置。我的设置为使用父/子视图控制器并嵌入 segue,但您可以将相同的方法用于模态表示、基于导航控制器的导航或各种其他应用程序结构。

回购有一个完全没用的名字“测试”。您可以在https://github.com/DuncanMC/test找到它

于 2013-09-25T17:45:01.993 回答