iOS在故事板中切换嵌入式视图

时间:2012-11-20 23:28:14

标签: ios views storyboard

我一直在努力解决这个问题,我知道它应该可以完成,但是对于使用Objective-C而不是Appcelerator的iOS开发新手我有新手问题。

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

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

感谢您提供任何帮助。

3 个答案:

答案 0 :(得分:6)

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

-(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];
}

答案 1 :(得分: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];
}

就是这样。没问题吧?! ;)

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

答案 2 :(得分:1)

我想做同样的事情,这就是我找到的。

Creating Custom Container View Controllers

它的主旨是创建一个嵌入容器视图的导航控制器,它允许您根据需要浏览多个视图。

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

  1. 将导航控制器添加到故事板。
  2. 将导航控制器嵌入容器视图中。
  3. 选择一个视图作为导航控制器的根视图控制器。
  4. 为将在容器视图中使用的每个视图控制器创建手动segue 包括ROOT VIEW CONTROLLER (我几乎错误地认为没有添加这个)。确保列出您创建的每个segue。
  5. 在您的代码中,只要您想要显示不同的视图控制器,只需调用相应的手动segue。
  6. 希望这有帮助!