7

我整天都在尝试解决这个问题,我知道它应该能够完成,但是对于使用 Objective-C 而不是 Appcelerator 进行 iOS 开发的新手,我遇到了新手问题。

我想要完成的是在我的其他视图之一中拥有一个嵌入式视图,但能够通过编程切换嵌入哪个视图。我正在使用故事板。当我尝试使用视图容器时,它会显示附加视图,但我无法将多个视图附加到情节提要中的容器。我画了一张图片,但令我烦恼的是,我无法在此处发布图片,因为我没有足够的“代表”点,所以我将其发布在我的网站上: http ://static.c6gx.com/images/iphone -embedded-views-diagram.jpg

稍后我希望在该视图容器中看起来像是一个推送 segue,但首先我只想能够在嵌入式视图 1、2、3 等之间切换。我应该使用视图容器来完成这个,还是其他类型的控制器?那么我如何调用转换来改变视图呢?

感谢您提供任何帮助。

4

3 回答 3

6

您可以像使用容器视图控制器一样切换视图控制器。我做了一个项目,在其中添加了一个容器视图(实际上是 2 个,但我们在这里只处理一个),并将此代码添加到嵌入式控制器中,当您在容器视图中拖动时会自动获得该控制器。我要切换到的控制器 NewRightController 是 UIViewController 子类——在情节提要中,我将控制器的大小设置为“自由形式”,并更改了视图的大小以匹配嵌入式控制器视图的大小。这实际上并不影响视图的大小(它仍然以全屏形式记录),它只是使布局子视图更容易。

-(IBAction)switchToNewRight:(id)sender {
    UIView *rcView = [(ViewController *)self.parentViewController rightView]; // rcView is the right container view in my root view controller that self is embedded in.
    NewRightController *newRight = [self.storyboard instantiateViewControllerWithIdentifier:@"NewRight"];
    newRight.oldRightController = self; // pass self to new controller so I can come back to the same instance
    newRight.view.frame = rcView.bounds;
    [self.parentViewController addChildViewController:newRight];
    [self moveToNewController:newRight];
}

-(void)moveToNewController:(UIViewController *) newController {
    UIView *rcView = [(ViewController *)self.parentViewController rightView];
    [self willMoveToParentViewController:nil];
    [self.parentViewController transitionFromViewController:self toViewController:newController duration:1 options:UIViewAnimationOptionTransitionCurlUp animations:^{}
         completion:^(BOOL finished) {
             [self removeFromParentViewController];
             [rcView constrainViewEqual:newController.view];
             [newController didMoveToParentViewController:self];
         }];
}

经过大量实验后,我发现使视图具有正确大小并在旋转后正确调整大小的方法是最初将新控制器视图的框架设置为容器视图的边界,但是在过渡动画之后,添加约束到旋转后保持其大小的新视图。由于这段代码可能会被反复使用,我将它放在 UIView 上的一个类别中,使用一种方法,即 constrainViewEqual:。这是代码:

-(void)constrainViewEqual:(UIView *) view {
    [view setTranslatesAutoresizingMaskIntoConstraints:NO];
    NSLayoutConstraint *con1 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:0 toItem:view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
    NSLayoutConstraint *con2 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
    NSLayoutConstraint *con3 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:0 toItem:view attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
    NSLayoutConstraint *con4 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:0 toItem:view attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
    NSArray *constraints = @[con1,con2,con3,con4];
    [self addConstraints:constraints];
}
于 2012-11-21T00:10:01.267 回答
1

我想做同样的事情,这就是我发现的。

创建自定义容器视图控制器

它的要点是您创建一个嵌入到容器视图中的导航控制器,它允许您根据需要在多个视图中导航。

这是一个简短的示例/演练:

  1. 将导航控制器添加到您的故事板。
  2. 将导航控制器嵌入到容器视图中。
  3. 选择一个视图作为导航控制器的根视图控制器。
  4. 为将在容器视图内部使用的每个视图控制器创建手动 segues,包括根视图控制器(我差点犯了不添加这个的错误)。确保为您创建的每个 segue 命名。
  5. 在您的代码中,只要您想显示不同的视图控制器,只需调用相应的手动 segue。

希望这可以帮助!

于 2013-08-03T14:34:21.440 回答
1

所以在玩了很多之后,我得到了它的工作,就像我想象的那样。此时它没有过渡,但我想发布代码供其他人查看。

在故事板中,我有一个用于整个游戏的视图控制器,其中有一个视图容器和一个按钮。嵌入到游戏视图中的视图是一个页面控制器,它将包含不同类型的问题。然后故事板中未附加的是不同类型的问题布局,在我的例子中是 teamDisplay 和 locationDisplay。

在 QuestionViewController 中,我向 .h 文件添加了两个属性:

@property (nonatomic, strong) UIPageViewController *pageViewController;
@property (nonatomic, strong) NSMutableArray *questionTypeViewControllers;

声明了一个方法:

-(void)changeView;

在 .m 文件中,合成它们:

@synthesize questionTypeViewControllers,
            pageViewController;

在 viewDidLoad 方法中:

pageViewController = [[UIPageViewController alloc]
        initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
        navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
        options:nil];

UIViewController *ldvc = [self.storyboard instantiateViewControllerWithIdentifier:@"locationDisplay"];
UIViewController *tdvc = [self.storyboard instantiateViewControllerWithIdentifier:@"teamDisplay"];

questionTypeViewControllers = [NSMutableArray arrayWithObjects:ldvc, tdvc, nil];

NSArray *initView = [NSArray arrayWithObject:ldvc];

[pageViewController setViewControllers:initView
                                      direction:UIPageViewControllerNavigationDirectionForward
                                       animated:NO
                                     completion:nil];
[self addChildViewController:pageViewController];
[self.view addSubview:self.pageViewController.view];

然后实现了changeView方法:

NSArray *initView = [NSArray arrayWithObject: [questionTypeViewControllers objectAtIndex:1]];
[pageViewController setViewControllers:initView
                                 direction:UIPageViewControllerNavigationDirectionForward
                                  animated:NO
                                completion:nil];

在按钮所在的 GameViewController 中,为按钮添加一个动作,并从 QuestionViewController 中调用新创建的 changeView 方法。

- (IBAction)change:(id)sender {
    // Need a more reliable way to get the QuestionViewController.
    [[self.childViewControllers objectAtIndex:0] changeView];
}

就是这样。不费吹灰之力吧?!;)

我不知道这是否是正确的方法,但它奏效了。欢迎任何建议或改进。

于 2012-11-21T18:04:11.690 回答