iOS在情节提要中切换嵌入式视图

iOS在情节提要中切换嵌入式视图,ios,views,storyboard,Ios,Views,Storyboard,我一整天都在试图弄明白这一点,我知道这应该是可以做到的,但作为使用Objective-C而不是Appcelerator进行iOS开发的新手,我遇到了一些新手问题 我试图实现的是在我的另一个视图中嵌入一个视图,但能够通过编程切换嵌入的视图。我用的是故事板。当我尝试使用视图容器时,它会显示附加的视图,但我无法将多个视图附加到故事板中的容器。我画了一张图片,但令我烦恼的是,我不能在这里发布图片,因为我没有足够的“代表”点数,所以我在我的网站上发布了它: 稍后,我希望在视图容器中出现一个推送序列,但首

我一整天都在试图弄明白这一点,我知道这应该是可以做到的,但作为使用Objective-C而不是Appcelerator进行iOS开发的新手,我遇到了一些新手问题

我试图实现的是在我的另一个视图中嵌入一个视图,但能够通过编程切换嵌入的视图。我用的是故事板。当我尝试使用视图容器时,它会显示附加的视图,但我无法将多个视图附加到故事板中的容器。我画了一张图片,但令我烦恼的是,我不能在这里发布图片,因为我没有足够的“代表”点数,所以我在我的网站上发布了它:

稍后,我希望在视图容器中出现一个推送序列,但首先我只希望能够在嵌入式视图1、2、3等之间切换。我应该使用视图容器来实现这一点,还是使用其他类型的控制器?那么我如何调用转换来更改视图


感谢您提供的帮助。

您可以像使用容器视图控制器一样切换视图控制器。我做了一个项目,在其中我添加了一个容器视图(实际上是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的一个类别中,使用一个方法ConstraintViewEqual:。以下是代码:

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

所以在玩了很多之后,我让它开始工作了,就像我想象的那个样。此时它没有转换,但我想发布代码供其他人查看

在故事板中,我有一个用于整个游戏的视图控制器,其中有一个视图容器和一个按钮。嵌入到游戏视图中的视图是一个页面控制器,它将包含不同类型的问题。然后,故事板中没有附加的是不同类型的问题布局,在我的例子中是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];
}
就这样。一个不需要动脑筋的人,对吧?!;)


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

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

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

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

  • 将导航控制器添加到情节提要中
  • 将导航控制器嵌入容器视图中
  • 选择一个视图作为导航控制器的根视图控制器
  • 为将在容器视图中使用的每个视图控制器创建手动分段,包括根视图控制器(我几乎犯了一个错误,没有添加这个)。确保为创建的每个序列命名
  • 在代码中,只要在需要显示不同的视图控制器时调用相应的手动segue即可

  • 希望这有帮助

    嵌入序列很奇怪,因为它们并不像您所期望的那样工作。您无法访问嵌入式视图控制器的视图继承人权限,因此必须创建自定义序列才能执行所需操作。或者,您可以在嵌入式控制器中安装一个PageController,并禁用滚动(然后手动翻页)。谢谢,我将试一试,看看我能想出什么。@RichardJ.RossIII,“您无法访问嵌入式视图控制器的视图继承权”——是的,事实上您可以。如果它是一个子类视图控制器,则可以像访问任何其他视图控制器一样访问视图层次结构。如果不是,那么您仍然可以通过家长的ChildViewController属性访问视图。我不知道您是否看到了我的原始帖子,但我发现我的部分工作代码有什么问题,并重新发布了我的答案。这是另一种可能的方法,与Richard提到的方法一样。谢谢,等我对Objective-C稍微熟悉一点后,我将不得不找出你的版本。现在我仍然有点困惑/不知所措。我已经让页面控制器版本正常工作了,所以我将暂时采用这种方式。我将在回答中发布我的代码,以便其他人可以查看。我不太清楚为什么会这样——你说你的故事板中有一个嵌入式pageViewController,但这里你正在实例化一个新的?为什么?你不应该那样做。如果在根视图控制器中嵌入了一个页面控制器,它将在启动时为您实例化。您可以使用childViewControllers属性从它嵌入的控制器中获取对它的引用。如何创建分段?是从导航控制器创建的吗?顺便说一句,链接不再有效。