开发者

Pass a UIViewController/UIView between the views of UITabBar tabs

Ultimately, I'd like to know how to store a UIView (globally, if necessary) from one view controller, so that it can be referenced, and called back up to the top, from within another view controller?

I've built an app that has a Home tab and a Guide tab as the two main tabs, but the Guide tab's functionality is a bit unique in that it's a dynamic tab, which will ideally show different content depending on what "guide" has been chosen from the Home tab. Thus, on the Home tab, there are several UIButtons that are meant to load a given guide. Each guide is simply a collection of images that the user can interact with. No problem there.

Now, on the Home tab, when a user selects the guide they want to view, I wanted to transition between the Home tab and the Guide tab with a CurlDown animated transition. This is the only place I'll have a UIView transition animation—mean开发者_JAVA百科ing normal tab switching by the user will be the standard instant transition without effects.

Here's how I have implemented the Home-to-Guide transition when a user selects a guide from the Home tab. This is done in the HomeViewController, as an IBAction assigned to all the guide-loading UIButtons, each of which has a unique tag that tells the GuideViewController which guide to load:

- (IBAction)loadGuide:(id)sender
{
UIButton *button = (UIButton*) sender;
GuideViewController *guideController = [[GuideViewController alloc] initWithNibName:@"GuideViewController" bundle:nil];
self.guideViewController = guideController;
[self.guideViewController activateGuide:button.tag];
[UIView transitionFromView:self.view
                    toView:guideController.view
                  duration:1.0
                   options:UIViewAnimationOptionTransitionCurlDown
                completion:^(BOOL finished){
                    UITabBarItem *tabBarGuide = [[self.tabBarController.tabBar items] objectAtIndex:1];
                    [tabBarGuide setEnabled:TRUE];
                    self.tabBarController.selectedIndex = 1;
                }];
[guideController release];
}
// End (IBAction)loadGuide

This works really well, up until the point where I then have to enable the Guide tab and switch to it. What happens at that point seems to be that another instance of the GuideViewController is created and replaces the one that was initially instantiated and transitioned to from the HomeViewController as shown above.

So I thought maybe I could work around it by, instead, moving the guide-loading to a new view, on that isn't used with the UITabBar, then load and transition to this view from the Home tab, just like I did in the above code. Then, after switching tabs, I'd need to somehow recall it into my Guide tab's view controller, as a subview or the like.

I'd think the view would still exist in memory after the tab-switching process, I just don't know how to access it, so I can show it again after the Guide tab's view has hidden it. Should I assign the view to some sort of globally accessible variable from the HomeViewController so that I can then access it from the GuideViewController (Guide tab's view)?

I'm open to any alternate suggestions as well, if you think this approach is bad form! I initially tried to overcome the problem by loading the details of the active guide into the database, then recovering that data when the Guide tab's view controller kicked in. However, the Guide tab's view must be cached or something, because if the user goes back to the home page and chooses a new guide, it'll animate the transition to that guide, but then when the Home-to-Guide-tab-switch kicks in, it flips back to the same state that the Guide tab's view was in before the user went back to the home page to choose a new tab. Also, I noticed the ViewDidLoad method doesn't get called again when manually nor programmatically switching tabs, so I figured that the other view must still be around in memory too! (The "other view" being either the original instance of the GuideViewController's view initiated from the Home tab upon selecting a guide button, or a new view as previously mentioned that would essentially do the same thing, albeit in a separate class.)

So to summarize:

  • I have two tabs, Home and Guide
  • Home has several UIButtons that when tapped will load a specific guide
  • When a UIButton on Home is tapped, it transitions from the Home tab's view to the Guide tab's view view CurlDown, without first switching to the Guide tab because that would lose the CurlDown effect
  • Then I have to trigger the tab switch programmatically, which seems to load a new instance of the Guide view, which effectively covers up the other instance
  • I want to know if I can somehow just call back up the first instance by somehow maybe storing the other instance as a global or some such?
  • Hense the question about how to pass a UIView instance around several UIViewControllers


If I were you I'd ditch the transition and just the tabbar as normal.

Firstly as it's giving you problems, but also and more importantly as it would seem strange to the end user who is used to tab bars just switching when you press the tab (well it would to me).

I'd read and re-read Apple's HIG on tabbars too. I think your users will find it very confusing that something other than the tab bar buttons causes the selected tab to switch.

You would have the data in the model. The home tab would specify to the model which guide is chosen. The guide would view load it's data every time it appears.

If you do need to keep the transition, then ditch the guide tab and use a navigationbar inside the home tab. You mention that screen space is the one issue for not doing so, but you can have the navigation bar present but not visible. You could then have a button in the guide tab to close that viewcontroller (pop the guide vc).

Another option might be to present the guide view modally instead - but the partial page curl also restricts screen space a little.


The ideal approach to doing this is to store a retained reference to the UIView object in a persistent object such as the app delegate subclass UIApplicationDelegate. The app delegate can then instantiate the view. Then, each controller needing to show the view would just ask the app delegate for the view. Also, if a root view controller is always available, it could be retained there as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜