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
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).
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)
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.
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
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.
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)
}
}
I had to add in the viewDidLoad() function the reference for the delegate:
self.tabBar.delegate = self
Otherwise the function func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem)
would never be called.
Using the platform style users are familiar with in your application is a good thing, but if you want more flexibility in where you place things and how you set up your hierarchy you might just better go with UITabBar directly and then implement the UITabBarDelegate separately.
https://developer.apple.com/library/ios/documentation/uikit/reference/UITabBar_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UITabBar
I always advocate not using UITableViewController and other specialized ViewControllers like UITabBarController because separating everything avoids clutter and makes your applications more flexible.
According to Apple's docs, a UITabBar
is not intended to put in navigation tools for a single view such as your UIWebView
, but to navigate between different views. So it is better to use a UIToolBar
instead.