devth devth - 3 months ago 28
iOS Question

Use a UITabBar without UITabBarController to control a UIWebView

I want to use a

UITabBar
to let the user navigate a single
UIWebView
. Is this possible or would I be better off using a
UIToolbar
? If better off using a
UIToolbar
, how would I simulate the "selected" visual state of a button, the way
UITabBar
natively does?

Answer

UITabBar without UITabBarController to control UIWebView

I have supplied the Objective-C as well as the Swift version to solve this problem. The only thing you really need to do is to implement the UITabBarDelegate protocol on a class. It doesn't have to be ViewController but in this simple example it is).

Objective-C solution in Xcode 5

In this Objective-C example you can switch between three search engines from the UITabBar.

First you have to set up your views, as follows: (You cannot set the delegate outlet unless you add the UITabBarDelegate to the ViewController first, see code)

enter image description here

Now because you don't have a direct reference to the items inside of the UITabBar because we set it all up in Interface Builder you need to set the tags on them. I'm not a huge fan of this method but if you take care it works just fine. If you want to set up something more complicated with dynamic loading buttons you should consider subclassing UITabBar.

enter image description here

Now the important thing here is that "tag" setting on the right. You need to set that up to a number for each of the buttons there. In this case I have set them to 0, 1 and 2 as that more or less correlates to how an array counts but you're free to choose any number.

Having set up this we can take a look at the code:

.h file:

#import <UIKit/UIKit.h>

@interface LVDViewController : UIViewController<UITabBarDelegate> 
// implementing the delegate allows you to drag and drop the delegate reference from the first screenshot

@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (weak, nonatomic) IBOutlet UITabBar *tabBar;

@end

.m file:

#import "LVDViewController.h"

@interface LVDViewController ()

@end

@implementation LVDViewController

- (void)viewDidLoad;
{
    [super viewDidLoad];
    // Set the first item as selected. It will automatically load Google
    [self tabBar:self.tabBar didSelectItem:[self.tabBar.items firstObject]];
    self.tabBar.selectedItem = [self.tabBar.items firstObject];
    // This is optional
}

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item;
{
    NSString *searchEngineURLString = nil;
    switch (item.tag)
    {
        case 0:
            searchEngineURLString = @"https://google.com";
            break;
        case 1:
            searchEngineURLString = @"https://duckduckgo.com";
            break;
        case 2:
            searchEngineURLString = @"https://bing.com";
            break;
    }

    [self loadSearchEngine:searchEngineURLString];
}

- (void)loadSearchEngine:(NSString *)searchEngineURLString;
{
    NSURL *searchEngineURL = [NSURL URLWithString:searchEngineURLString];
    NSURLRequest *searchEngineRequest = [NSURLRequest requestWithURL:searchEngineURL];
    [self.webView loadRequest:searchEngineRequest];
}

@end

Swift solution in Xcode 6

Now we have the Objective-C version working it's time for the Swift version of this. First we setup our View in Interface Builder again, this time Bing is the favorite search engine instead of Google to reflect the new Apple viewpoint. It's almost identical and you also have to add the tags to the tab bar items again.

enter image description here

We have our View Controller again, but now we are using Swift so it's only one file:

import UIKit

class ViewController: UIViewController, UITabBarDelegate {
    @IBOutlet var tabBar : UITabBar
    @IBOutlet var webView : UIWebView

    override func viewDidLoad() {
        super.viewDidLoad()

        loadSearchEngine("https://www.bing.com")
        tabBar.selectedItem = tabBar.items[0] as UITabBarItem;
    }

    func tabBar(tabBar: UITabBar!, didSelectItem item: UITabBarItem!) {
        var searchEngineURLString: NSString! = "";

        switch item.tag  {
        case 0:
            searchEngineURLString = "https://www.bing.com"
            break
        case 1:
            searchEngineURLString = "https://www.duckduckgo.com"
            break
        case 2:
            searchEngineURLString = "https://www.google.com"
            break
        default:
            searchEngineURLString = "https://www.bing.com"
            break
        }

        loadSearchEngine(searchEngineURLString);
    }

    func loadSearchEngine(searchEngineURLString: NSString!) {
        var searchEngineURL = NSURL(string: searchEngineURLString)
        var searchEngineURLRequest = NSURLRequest(URL: searchEngineURL)
        webView.loadRequest(searchEngineURLRequest)
    }
}