{"id":204,"date":"2011-11-09T22:22:42","date_gmt":"2011-11-09T20:22:42","guid":{"rendered":"http:\/\/www.smartersoftware.de\/wordpress\/2011\/11\/building-an-info-screen-for-your-ios-app-using-uiwebview\/"},"modified":"2011-11-09T22:22:42","modified_gmt":"2011-11-09T20:22:42","slug":"building-an-info-screen-for-your-ios-app-using-uiwebview","status":"publish","type":"post","link":"http:\/\/www.smartersoftware.de\/wordpress\/2011\/11\/building-an-info-screen-for-your-ios-app-using-uiwebview\/","title":{"rendered":"Building an info screen for your iOS app using UIWebView"},"content":{"rendered":"<p>For my upcoming iPhone app I was looking for an easy way to add an info screen that describes the app and some of the features. I found a lot of mentions of \u201cuse UIWebView\u201d, but I couldn\u2019t find a comprehensive tutorial or list of steps. So here is a description of the implementation I came up with and some issues that I ran into.<\/p>\n<h2>Building the View<\/h2>\n<p>The view is relatively simple \u2013 all it has is an instance of UIWebView. Here is the header file:<\/p>\n<pre class=\"brush: plain;\">#import &lt;UIKit\/UIKit.h&gt;\n\n@interface InfoViewController : UIViewController &lt;UIWebViewDelegate&gt; {\n    UIWebView *webView;\n}\n@property (nonatomic, retain) UIWebView *webView;\n\n@end<\/pre>\n<p>In the init-method, the UIWebView is instantiated and made to use the whole area:<\/p>\n<pre class=\"brush: plain;\">- (id) init {\n    [super init];\n    if (self) {\n        \/\/set title to navItem\n        [[self navigationItem] setTitle:@&quot;Info&quot;];\n\n        \/\/ add webView\n        CGRect bounds = [self.view bounds];\n        bounds.size.height = bounds.size.height - 48; \/\/height for navItem        \n        webView = [[UIWebView alloc] initWithFrame: bounds];\n        webView.delegate = self;\n        \n        [[self view] addSubview:webView];\n    }\n    return self;\n}<\/pre>\n<p>I\u2019m not really happy with the \u201cmagical\u201c 48 pixels to account for the navItem, but at least it\u2019s working fine. (If you have a better way, please let me know!)<\/p>\n<h2>Displaying Info Text<\/h2>\n<h3>Displaying HTML<\/h3>\n<p>Once the view is initialized, displaying an HTML-page such as help.html is pretty simple:<\/p>\n<pre class=\"brush: plain;\">- (void) viewWillAppear:(BOOL)animated {\n    [super viewWillAppear:animated];\n    \n    \/\/build a request to display help.html\n    [webView loadRequest:[NSURLRequest requestWithURL:\n            [NSURL fileURLWithPath:[\n                [NSBundle mainBundle] pathForResource:@&quot;help&quot; ofType:@&quot;html&quot;]\n                    isDirectory:NO]]];\n}<\/pre>\n<p>You just have to add the file help.html to your project and make sure it is part of the target. It gets copied to the simulator or iPhone as part of the installation procedure. You can also include some CSS to properly style the html document (especially for aspects such as fonts or padding).<\/p>\n<h3>Displaying local images<\/h3>\n<p>In order to display images in the html, you just have to reference like this in the html-file:<\/p>\n<pre class=\"brush: plain;\">&lt;img src=&quot;ScreenshotTop.png&quot; alt=&quot;Screenshot Top Part&quot; width=&quot;288&quot; height=&quot;214&quot;\/&gt;<\/pre>\n<p>If you google for \u201cUIWebView local image\u201d, there are a lot of references to setting the baseURL of the UIWebView. I couldn\u2019t get this to work properly, but instead found that simple references to png-files just work (whereas jpg-files did not work). <\/p>\n<p>As with all images, they should be properly scaled to the dimensions that you want them to be displayed in order to avoid any re-sizing on the device which can take quite some time for screenshots.<\/p>\n<h2>Displaying the view<\/h2>\n<h3>Adding an Info Button to the Navigation Bar<\/h3>\n<p>There is a standard info button (UIButtonTypeInfoLight) that is ideal for an info screen, but it can\u2019t be used directly in a navigation bar. I order to use this standard button, you have to wrap this button in an UIBarButtomItem:<\/p>\n<pre class=\"brush: cpp;\">UIButton* infoButton = [UIButton buttonWithType: UIButtonTypeInfoLight];\n[infoButton addTarget:self action:@selector(showInfo) forControlEvents:UIControlEventTouchUpInside];\nUIBarButtonItem *infoBarButton = [[UIBarButtonItem alloc] initWithCustomView:infoButton];\n[self.navigationItem setRightBarButtonItem: infoBarButton animated:YES];\n[infoBarButton release];\n[infoButton release];<\/pre>\n<h3>Showing the info view<\/h3>\n<p>In order to show the view, you just initialize the InfoViewController and push it on the display stack:<\/p>\n<pre class=\"brush: plain;\">-(void) showInfo {\n    if (!infoViewController) {\n        infoViewController = [[InfoViewController alloc] init];\n    }\n    [[self navigationController] pushViewController:infoViewController animated:YES];    \n}<\/pre>\n<h2>Handling Links<\/h2>\n<p>When you include links in your html-file (such as to your website, to your product FAQ on the web or a mailto: your support email address), you want them to open in the corresponding app (and not in your UIWebView). In order to do that, you have to implement the UIWebViewDelegate protocol in your InfoViewController, especially the following method:<\/p>\n<pre class=\"brush: plain;\">-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; \n{\n    if ((navigationType == UIWebViewNavigationTypeLinkClicked) || ([request.URL.scheme isEqualToString:@&quot;mailto&quot;])) {\n        [[UIApplication sharedApplication] openURL:request.URL];\n        return false; \/\/will open links in Safari or MailApp\n    } else {\n        return true;\n    }\n} <\/pre>\n<p>This method is called whenever a request starts to be loaded in the UIWebView. It looks if is called because a link was clicked (NavigationTypeLinkClicked) or the URL scheme is \u201cmailto\u201d. If that\u2019s the case then we open that link in the \u201csharedApplication\u201d which is Safari (for web pages) or the MailApp (for mailto\u2019s).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For my upcoming iPhone app I was looking for an easy way to add an info screen that describes the app and some of the features. I found a lot of mentions of \u201cuse UIWebView\u201d, but I couldn\u2019t find a comprehensive tutorial or list of steps. So here is a description of the implementation I [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32],"tags":[],"class_list":["post-204","post","type-post","status-publish","format-standard","hentry","category-ios"],"_links":{"self":[{"href":"http:\/\/www.smartersoftware.de\/wordpress\/wp-json\/wp\/v2\/posts\/204","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.smartersoftware.de\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.smartersoftware.de\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.smartersoftware.de\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.smartersoftware.de\/wordpress\/wp-json\/wp\/v2\/comments?post=204"}],"version-history":[{"count":0,"href":"http:\/\/www.smartersoftware.de\/wordpress\/wp-json\/wp\/v2\/posts\/204\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.smartersoftware.de\/wordpress\/wp-json\/wp\/v2\/media?parent=204"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.smartersoftware.de\/wordpress\/wp-json\/wp\/v2\/categories?post=204"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.smartersoftware.de\/wordpress\/wp-json\/wp\/v2\/tags?post=204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}