iOS Switching an embedded view in storyboard

后端 未结 3 1002
予麋鹿
予麋鹿 2021-02-04 18:16

I have been trying to figure this out all day and I know it should be able to be done, but being new to iOS development using Objective-C and not Appcelerator I\'m having newbie

相关标签:
3条回答
  • 2021-02-04 18:18

    So after much playing around I got it to work, kind of the way I envisioned. It has no transitions at this point, but I wanted to post the code for others to view.

    In the storyboard I have a view controller for the entire game, that has a view container in it and a button. The view embedded into the game view is a page controller that will contain the different type of questions. Then unattached in the storyboard are the different type of question layouts, in my case the teamDisplay and locationDisplay.

    In the QuestionViewController, I added two properties to the .h file:

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

    Declared a method:

    -(void)changeView;
    

    In the .m file, synthesized them:

    @synthesize questionTypeViewControllers,
                pageViewController;
    

    In the viewDidLoad method:

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

    And then implemented the changeView method:

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

    In the GameViewController, where the button is located, add an action to the button and call the newly created changeView method from the QuestionViewController.

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

    And that is it. A no brainer right?! ;)

    I have no idea if this is the proper way to do this, but it worked. Any suggestions or improvements are welcome.

    0 讨论(0)
  • 2021-02-04 18:24

    I wanted to do the same thing, and this is what I found.

    Creating Custom Container View Controllers

    The gist of it is you create a navigation controller that you embed into the container view, which allows you to navigate through several views as you wish.

    Here's a short example/walkthrough:

    1. Add a Navigation Controller to your Storyboard.
    2. Embed the Navigation Controller inside of the Container View.
    3. Select a view to be the root view controller of the navigation controller.
    4. Create manual segues for each view controller that will be used inside of the container view, INCLUDING THE ROOT VIEW CONTROLLER (I almost made the mistake of not adding this one). Make sure you name each segue you create.
    5. In your code, simply call the corresponding manual segue whenever you want to show a different view controller.

    Hope this helps!

    0 讨论(0)
  • 2021-02-04 18:43

    You can switch the view controllers like you would do with a container view controller. I made a project where I added a container view (2 actually, but we're only dealing with one here), and added this code to the embedded controller that you get automatically when you drag in the container view. The controller I'm switching to, NewRightController, is a UIViewController subclass -- in the storyboard I set the controller's size to "Freeform", and changed the size of the view to match the size of the embedded controller's view. This doesn't actually affect the size of the view (it still logs as full screen), it just makes it easier to layout the subviews.

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

    I found after much experimentation that the way to get the views to be the right size and to resize properly after rotation was to initially set the frame of the new controller's view to the container view's bounds, but then after the transition animation, add constraints to the new view that keep it sized right after rotation. Since this code might be used over and over, I put it in a category on UIView, with one method, constrainViewEqual:. Here is the code for that:

    -(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];
    }
    
    0 讨论(0)
提交回复
热议问题