Domanda

I'm working on a project with some folks who want to use TTNavigator rather than Storyboards or old-fashioned UINavigationController pushing. Fine by me, except some view controllers in our app are using the delegate pattern to communicate with each other. I'm not sure how to preserve that pattern while using TTNavigator. Is it possible?

Another way of asking my question is: is it possible to access the destination view controller from within the view controller that is telling TTNavigator to open a new actionURL to that destination view controller?

For example, I have a view controller that wants an image from the user. To get it, it launches a new view controller with a camera UI that allows the user to get the image. Normally, I would set the first view controller as the delegate of the camera view controller. When the user has chosen an image, the camera view controller tells the delegate about the selection, and the delegate grabs the image and pops the camera view controller off the stack.

TTNavigator doesn't seem to give my first view controller a chance to interact with the camera view controller. The one way I see is for the first view controller to set itself as the delegate of the TTNavigator, which will result in the TTNavigator giving me a peek at the view controller it's about to push. Is that the best way to handle this?

È stato utile?

Soluzione

It is possible but not recommended

You can pass data in the "query". You could certainly pass your origin viewController and then wire that up in the constructor of the destination viewController. Its loosely coupled and would work just fine. Its not pretty, though.

http://three20.info/article/2010-10-06-URL-Based-Navigation#nativeparams

Alternately, you could retrieve the viewController directly form the TTNavigator using viewControllerForURL: and then push that viewController. Also not pretty

I used TTNavigator on many projects but the last implementation was far more trouble than it was worth. We tried to make it work on an iPad project and constantly fought with the library. The bottom line is that iOS apps are just not web apps and there is no universal strategy for mapping a url to multiple screen navigation within a custom app. It makes perfect sense for web where each page is stateless and lives within a structured semantic architecture (hopefully) but with a rich mobile app, particularly a multi-pane iPad app, these details are not easily encoded in a url. You are better off building a less complicated navigation management sub system and then mapping explicit urls as you need them.

Altri suggerimenti

Ironically, I had a similar issue while using the facebook-ios-sdk in order to add facebook support to one of my three20 apps. my controller expected to get the Facebook url response, however, it was impossible to use the standard TTNavigator url mapping.

I had to find a way to call the Facebook object on the controller to pass the incoming url. when TTNavigator manage the controller stack for you, you can't "access" the controllers from anywhere else besides the controller itself.

I ended up setting the controller has a private parameter of the app delegate and using that in the TTURLMap.

@class PhotoEditorController;

@interface PhotoBoothAppDelegate : NSObject <UIApplicationDelegate> {
  PhotoEditorController* _photoEditorController;
}

@property(nonatomic, retain) PhotoEditorController* photoEditorController;
@end


///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
@implementation PhotoBoothAppDelegate

@synthesize photoEditorController = _photoEditorController;



///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark UIApplicationDelegate


///////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO];

    TTNavigator* navigator = [TTNavigator navigator];
    navigator.persistenceMode = TTNavigatorPersistenceModeNone;

    navigator.window = [[UIWindow alloc] initWithFrame:TTScreenBounds()];

    TTURLMap* map = navigator.URLMap;

  _photoEditorController = [[PhotoEditorController alloc] init];

    // Any URL that doesn't match will fall back on this one, and open in the web browser
    [map from:@"*" toViewController:[TTWebController class]];

  [map from:@"tt://photo" toViewController:_photoEditorController transition:UIViewAnimationTransitionCurlUp];


  // Before opening the tab bar, we see if the controller history was persisted the last time
    if (![navigator restoreViewControllers]) {
        [navigator openURLAction:[TTURLAction actionWithURLPath:@"tt://intro"]];
    }

  return YES;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {  
  return [[_photoEditorController facebook] handleOpenURL:url];
}

This code still uses the TTNaviagtor, however, you still have references to the controllers, meaning you can directly access their parameters.

Overall, I would strongly suggest avoiding TTNavigator. Its iPad support is almost nonexistent and broken.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top