Question

Goal: For connection to iOS Google Drive, wrap the iOS Google OAuth view controller in a programmatically created navigation controller, and add a Cancel button to enable the user to cancel the Google OAuth process, should they choose to do so.

Problem: While I can successfully wrap the OAuth view controller in a navigation controller, I cannot seem to add a navigation item, such as the desired Cancel button.

I add a navigation controller that wraps the Google Drive OAuth view controller, as follows...

GTMOAuth2ViewControllerTouch *authViewController = nil;
if (!self.isAuthorized) {
    SEL selectorFinish = @selector(viewController:finishedWithAuth:error:);
    SEL selectorButtonCancel = @selector(buttonCancelTapped:);

    authViewController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDrive
                                                                    clientID:kClientID
                                                                clientSecret:kClientSecret
                                                            keychainItemName:kKeychainItemName
                                                                    delegate:self
                                                            finishedSelector:selectorFinish];

    UINavigationController *navController = [[UINavigationController alloc] init];

    [navController addChildViewController:authViewController];

    [self.parentTVC presentViewController:navController animated:YES completion:nil];
}

For clarity, the variable parentTVC is a public property,

@property (nonatomic, strong) UITableViewController *parentTVC;

and is set using a custom init method, as follows...

- (id)initWithParentTVC:(UITableViewController *)tvc {
    self = [super init];
    [self setParentTVC:tvc];

    return self;
}

I have attempted to add UINavigationItems to the UINavigationController instance navController, however this does not work, and instead I seem to be stuck with the UIView with the two small buttons (< and >) in the nib file GTMOAuth2ViewTouch.xib, image included below...

GTMOAuth2ViewTouch.xib

I have read through the GTL file GTMOAuth2ViewControllerTouch.m to attempt to see whether there is a method I could possible use or whether I can override by subclassing, but I am not confident in my attempts to do this.

My best guess is that any navigation controller wrapping the OAuth view controller set by this code from GTMOAuth2ViewControllerTouch.m...

- (void)setUpNavigation {
  rightBarButtonItem_.customView = navButtonsView_;
  self.navigationItem.rightBarButtonItem = rightBarButtonItem_;
}

Assistance please?

Was it helpful?

Solution

This is my re-interpretation of Imran Khan's excellent answer provided in his response to this stack overflow question: Google Drive iOS SDK: Display Cancel Login Button

The googleAuthCheck method should be called in either the viewDidLoad or viewWillAppear method of the parent view controller. (I assume here a reasonable understanding of iOS Google Drive SDK, so let me know if I need to add further clarification.)

Also, albeit a small issue, using initWithBarButtonSystemItem:UIBarButtonSystemItemCancel requires that only the title text of the view controller then needs to be localised (if you are implementing localisation).

- (void)googleAuthCheck {
    if (!self.isAuthorized) {
        SEL selectorFinish = @selector(viewController:finishedWithAuth:error:);
        SEL selectorButtonCancel = @selector(buttonCancelTapped:);

        UINavigationController *navController = [[UINavigationController alloc] init];

        UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:<<localised string for title>>];
        UIBarButtonItem *barButtonItemCancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:selectorButtonCancel];
        UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 320, 63)];

        [navigationItem setRightBarButtonItem:barButtonItemCancel];
        [navigationBar setTranslucent:NO];
        [navigationBar setItems:[NSArray arrayWithObjects: navigationItem,nil]];

        [navController.view addSubview:navigationBar];

        GTMOAuth2ViewControllerTouch *authViewController = nil;
        authViewController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:kGTLAuthScopeDrive
                                                                        clientID:kClientID
                                                                    clientSecret:kClientSecret
                                                                keychainItemName:kKeychainItemName
                                                                        delegate:self
                                                                finishedSelector:selectorFinish];

        [navController addChildViewController:authViewController];

        [self.parentTVC presentViewController:navController animated:YES completion:nil];
    }
}

For clarity, the buttonCancelTapped: method is as follows...

- (IBAction)buttonCancelTapped:(UIBarButtonItem *)sender {
    [self.parentTVC dismissViewControllerAnimated:YES completion:^(void){}];
}

For clarity, the variable parentTVC is a public property,

@property (nonatomic, strong) UITableViewController *parentTVC;

and is set using a custom init method, as follows...

- (id)initWithParentTVC:(UITableViewController *)tvc {
    self = [super init];
    [self setParentTVC:tvc];

    return self;
}

This custom init method is called from the parent view controller.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top