Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to display a SFSafariViewController inside of a UITabBarController?

I want to load SFSafariViewController inside of a tab, so the tab bar is at the bottom of the entire Safari view.

Is this possible? I tried this with no luck:

[self.tabBarController presentViewController:sfController animated:YES completion:nil];

Is it required that the Safari view be full screen?

like image 988
Ethan Allen Avatar asked May 07 '16 03:05

Ethan Allen


2 Answers

I was able to achieve this programmatically. They key to not have the UITabBar overlay on top of your UIViewController is to set translucent to NO:

In your AppDelegate.m:

@import SafariServices;

// ...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

    UITabBarController *tabBarController = [[UITabBarController alloc] init];
    tabBarController.tabBar.translucent = NO;

    SFSafariViewController *firstVC = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:@"http://stackoverflow.com"]];

    firstVC.title = @"SFSafariViewController";

    UIViewController *secondVC = [[UIViewController alloc] init];
    secondVC.view.backgroundColor = [UIColor blueColor];

    secondVC.title = @"Blue VC";

    tabBarController.viewControllers = @[firstVC, secondVC];

    self.window.rootViewController = tabBarController;
    [self.window makeKeyAndVisible];

    return YES;
}
like image 155
JAL Avatar answered Nov 15 '22 20:11

JAL


Using JAL's answer as a base, I was able to implement this myself in an app that had existing structure with tabs already.

I wanted tab #3 to go into a Safari controller within the tab after a button was pressed on the existing view, and not pop the Safari controller into its own window like it does using Apple's default code.

The key was to swap in a SFSafariViewController into the existing UITabBarController's array of view controllers. I saved the existing original view controller on tab #3 (index 2) to come back to it when the Done button was pressed on the Safari controller.

Here's what I did to go into the Safari controller from with my tab when a button was pressed:

NSMutableArray *viewArray = [NSMutableArray arrayWithArray:self.tabBarController.viewControllers];
self.savedController = [viewArray objectAtIndex:2];
[viewArray replaceObjectAtIndex:2 withObject:safariController];
self.tabBarController.viewControllers = viewArray;
[self setTabIconTitle];

Then I could swap back to the original view on that tab like this when the Done button was pressed on the Safari controller using this delegate call:

- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller
{
    UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
    NSMutableArray *viewArray = [NSMutableArray arrayWithArray:tabBarController.viewControllers];
    [viewArray replaceObjectAtIndex:2 withObject:self.savedController];
    tabBarController.viewControllers = viewArray;
    [self setTabIconTitle];
}

When I swapped controllers in an out of the tabBarController view controller array, I lost my tab icon and tab name, so I had to set those. Here is how I fixed that issue (and kept my theming when the tab icon was touched):

- (void)setTabIconTitle
{
    UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
    UITabBar *tabBar = tabBarController.tabBar;
    UITabBarItem *marketplaceTab = [tabBar.items objectAtIndex:2];
    marketplaceTab.image = [[UIImage imageNamed:@"tab2-icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    marketplaceTab.selectedImage = [UIImage imageNamed:@"tab2-icon"];
    marketplaceTab.title = @"My Tab";
}

I must admit that I am not sure that Apple intended that the SFSafariViewController be used in this way within a tab, based on what the normal behavior of calling SFSafariViewController currently does. Just be aware that future iOS updates may change this behavior and always test your code when new iOS versions go into Beta.

like image 35
Ethan Allen Avatar answered Nov 15 '22 19:11

Ethan Allen