如何从另一个视图控制器呈现视图控制器

时间:2012-01-30 02:36:53

标签: objective-c ios cocoa-touch

如果满足某些条件,我试图从另一个ViewController中打开一个ViewController。代码似乎运行没有错误,但视图永远不会显示。我是xcode 4 / ios 5的新手,所以我必须遗漏一些东西。

以下是负责打开第二个viewcontroller的代码:

CreateUserViewController *createUserController = [[CreateUserViewController alloc] initWithNibName:@"CreateUserView" bundle:[NSBundle mainBundle] keyWrapper:keyChainWrapper];

    [self presentViewController:createUserController animated:YES completion:nil];

在我的项目中,我有一个名为“CreateUserView”的xib。我已经为这个xib添加了一个视图控制器并将其分配给“CreateUserViewController”。

我还注意到在apple文档中显示了设置viewcontroller的委托。但似乎没有名为“delegate”的属性在viewcontroller对象上。这个文件是旧的吗?这是我试图使用的文件(第9-1节):

View Controller Programming

有人可以给我一个提示吗?感谢..

编辑添加自定义构造函数

    -(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil keyWrapper:(KeychainItemWrapper *)keyWrapper
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if(self){
        [self setKeyChainWrapper:keyWrapper];
    } 
             return self;
}

2 个答案:

答案 0 :(得分:4)

关于CreateUserView.xib:您不希望在笔尖中放置CreateUserViewController个对象。您希望将文件所有者占位符的自定义类设置为CreateUserViewController。然后,您需要将文件所有者的view出口连接到笔尖中的顶级视图。

关于delegate属性:UIViewController类没有自己的delegate属性。我们的想法是将delegate属性添加到UIViewController的子类中。委托为您呈现的视图控制器提供了一种将自定义信息传递回呈现视图控制器的方法。

你为什么要那样做?让我们考虑一下您发布的代码。我假设你有一个显示用户对象列表的UserListViewController,并且有一个“创建新用户”按钮。当用户触摸“创建新用户”按钮时,您创建一个CreateUserViewController并显示它。

用户与CreateUserViewController交互以设置新用户对象的属性 - 名称,等级,发型等。然后他触摸“完成”按钮。您的CreateUserViewController创建新的User对象并将其放入数据库中。然后它需要解雇自己,因此UserListViewController的用户对象列表将再次出现。

但是您希望用户列表包含新创建的用户对象,并且您希望滚动列表以便新用户在屏幕上。因此,您需要一种方法让CreateUserViewController告诉UserListViewController有关新创建的User对象的信息。这是代表进来的地方。

您可以定义这样的协议:

@protocol CreateUserViewControllerDelegate

- (void)didCreateUser:(User *)user;

@end

并且您为CreateUserViewController delegate属性提供了

@interface CreateUserViewController

@property (weak, nonatomic) id<CreateUserViewControllerDelegate> delegate;

// ...

当您触摸CreateUserViewController的“完成”按钮时,您会通知您的新用户代表:

- (IBAction)doneButtonWasTouched:(id)sender {
    User *user = [self createUser];
    [self.delegate didCreateUser:user];
    [self dismissViewControllerAnimated:YES completion:nil];
}

UserListViewController中,您采用并实施协议:

@interface UserListViewController <CreateUserViewControllerDelegate, UITableViewDelegate, UITableViewDataSource>

// ...

@end

@implementation UserListViewController

- (void)didCreateUser:(User *)user {
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[self.users count] inSection:0];
    [self.users addObject:user];
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationAutomatic];
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition: UITableViewScrollPositionNone animated:YES];
}

当您需要提交CreateUserViewController时,您将新控制器的委托设置为UserListViewController

- (IBAction)createUserButtonWasTouched:(id)sender {
    CreateUserViewController *createUserController = [[CreateUserViewController alloc] initWithNibName:@"CreateUserView" bundle:[NSBundle mainBundle] keyWrapper:keyChainWrapper];
    createUserController.delegate = self;
    [self presentViewController:createUserController animated:YES completion:nil];
}

答案 1 :(得分:1)

在iOS5中,用于推送新视图控制器的方法在iOS4和Xcode 3中实际上已经发生了很大变化。总之,故事板现在用于创建应用程序视图控制器流。即使您可以使用独立的.xib文件来构建应用程序,但在iOS5中它也不常见。

无论如何,将新视图控制器推送到屏幕上的主要方法是使用segues完成的。查看本教程的介绍:http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1

它在解释如何创建故事板和使用segue方面做得很好。您仍然可以在代码中呈现视图控制器&#34;旧方式&#34;但随着这些新技术的引入,现在却不那么常见了。 iTunes U上还有一些非常棒的教程 - 搜索CS193P。它是Objective-C的Stanford入门课程和iOS编程。这应该可以帮助您开始,也许可以帮助您想出一种方法来推动您的createUserController以更快的速度推进iOS5。

<强>更新

我只想补充一下。如果您将程序配置为使用故事板和segues,则可以使用performSegueWithIdentifier:sender:方法在满足适当条件的情况下执行segue到createUserController视图。有关如何使用此方法的信息,请参阅Apple API for UIViewController。