3

Retrospective of multiple views to display at different times

 2 years ago
source link: https://www.codesd.com/item/retrospective-of-multiple-views-to-display-at-different-times.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Retrospective of multiple views to display at different times

advertisements

I have an application that should show one of a set of different views depending on values reported by the accelerometer. I would like to set the views up in the Storyboard Editor in Xcode, née Interface Builder. Further, I would like to use Xcode's new-ish Auto Layout tools. Basically, these tools allow you to define inter-object constraints, and the runtime system figures out where said objects go.

Here's a simple example of what I want, in pseudo-code:

if (accelerometer == toTheLeft) {
    [topLevelView showSubview:leftView];
} else if (accelerometer == toTheRight) {
    [topLevelView showSubview:rightView];
} else {
    [topLevelView showSubview:centerView];
}

I know that to do the fictional showSubview: method, I'll actually have to remove whatever incorrect view is currently displayed, and add the one I want, but that's not the point here.

As mentioned before, I'd like to lay out each of these UIView objects (that is, leftView, rightView, and centerView) using Storyboard Editor/Interace Builder. When I go to do so, though, I end up with a confusing mess of different views stacked up on each other in IB. My view controller will ultimately add and remove the views from its view, but setting up the auto layout stuff is pretty hard this way.

Here's my question, finally. Is there a better way to have many, often overlapping views arranged straight-forwardly in the Storyboard editor for one view controller, or do I just have to set everything programmatically?


My introspective FAQ, for the avid reader:

  1. Why are you so set on Storyboard Editor/IB? It offers to automatically figure out a lot of the painful parts of view positioning and sizing. That sounds great! If I possibly can, I want to make it work for me.

  2. Someone must have asked this before, right? Uh, sorta. This question comes closest, out of those I found. However, this solution would still require me to set frames programmatically, negating what seems to me to be the best reason to use IB at all – auto-layout. This one got me excited, too, but isn't really about the same thing.


I had a similar situation in an application I was working on. What I did was that I added two container views to my main view controller (though you sound like you'll only need one). I deleted the embedded views within the containers, and added them as IBOutlets to my header file:

@property (weak, nonatomic) IBOutlet UIView *topContainerView;
@property (weak, nonatomic) IBOutlet UIView *bottomContainerView;

I then proceeded to create UIViewControllers for each of the three child views I wanted to use, which I could then design via the storyboard.

In my implementation file, I had two more properties,

@interface WorkOrderContainerViewController ()
@property UIViewController *topViewController;
@property UIViewController *bottomViewController;
@end

To switch between which of my view controllers was displayed, I used the following methods (I also had two similar methods for the bottom container view):

- (void)presentTopViewController:(UIViewController *)viewController
{
    // Remove current top view controller.
    if (topViewController != nil) {
        [self removeTopViewController];
    }

    [self addChildViewController:viewController];
    [[viewController view] setFrame:[topContainerView bounds]];
    [topContainerView addSubview:[viewController view]];
    [self setTopViewController:viewController];
    [viewController didMoveToParentViewController:self];
}

- (void)removeTopViewController
{
    [topViewController willMoveToParentViewController:nil];
    [[topViewController view] removeFromSuperview];
    [topViewController removeFromParentViewController];
}

I could then simply instantiate my views with

[self presentTopViewController:[storyboard instantiateViewControllerWithIdentifier:@"leftView"]];

I know you were looking for a way to manage overlapping views, but it'd probably be easier just to have each as a separate view controller and do it this way.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK