cs193p – Project #4 Assignment #4 Extra Task #4

By Wilgengebroed on Flickr [CC BY 2.0 (http://creativecommons.org/licenses/by/2.0)], via Wikimedia Commons

Please note, this blog entry is from a previous course. You might want to check out the current one.

Instead of opening urls in Safari, display them in your application by segueing to a controller with a UIWebView. You’ll have to provide at least a little bit of “browser control” UI to go along with it (e.g. a “back button”).

Add a new view controller to the storyboard. Add a egue from the mentions table view controller to the new controller (be careful, not from a cell, but from the controller itself!). Add a web view, an activity indicator and a back button (don’t forget constraints for autolayout):

cs193p - Project #4 Assignment #4 Extra Task #4 - web view controller
cs193p – Project #4 Assignment #4 Extra Task #4 – web view controller


Create a new class for the new controller and connect them. Add outlets for the web view and the activity indicator. Add an action for the back button:
[swift]
@IBOutlet weak var webView: UIWebView!
@IBOutlet weak var spinner: UIActivityIndicatorView!
@IBAction func back(sender: UIBarButtonItem) {
}
[/swift]

Add a public property to hold the URL. When it gets set and it has a chance to appear on screen, start loading the URL, or at least when the view did load:
[swift]
var url: NSURL? {
didSet {
if view.window != nil {
loadURL()
}
}
}
private func loadURL() {
if url != nil {
webView.loadRequest(NSURLRequest(URL: url!))
}
}
override func viewDidLoad() {
super.viewDidLoad()
webView.scalesPageToFit = true
loadURL()
}
[/swift]

Make the the controller the delegate of the web view and use its delegate method to start and stop the activity indicator depending on the status of the downloads:
[swift]
class WebViewController: UIViewController, UIWebViewDelegate {
override func viewDidLoad() {

webView.delegate = self

}

var activeDownloads = 0

func webViewDidStartLoad(webView: UIWebView) {
activeDownloads++
spinner.startAnimating()
}

func webViewDidFinishLoad(webView: UIWebView) {
activeDownloads–
if activeDownloads < 1 {
spinner.stopAnimating()
}
}
}
[/swift]

… and an actual activity to the action when the back button gets pressed:
[swift]
@IBAction func back(sender: UIBarButtonItem) {
webView.goBack()
}
[/swift]

In the mentions table view controller – where up to now the safari was called – perform the new segue and set the URL of the web view controller:
[swift]
private struct Storyboard {

static let WebSegueIdentifier = "Show URL"
}

override func shouldPerformSegueWithIdentifier(identifier: String?, sender: AnyObject?) -> Bool {

if url.hasPrefix("http") {
performSegueWithIdentifier(Storyboard.WebSegueIdentifier, sender: sender)
return false
}

}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

} else if identifier == Storyboard.WebSegueIdentifier {
if let wvc = segue.destinationViewController as? WebViewController {
if let cell = sender as? UITableViewCell {
if let url = cell.textLabel?.text {
wvc.url = NSURL(string: url)
}
}
}
}

}
[/swift]

The complete code for extra task #4 is available on GitHub.

Facebooktwittergoogle_plusredditpinterestlinkedintumblrmailFacebooktwittergoogle_plusredditpinterestlinkedintumblrmail

Leave a Reply

Your email address will not be published. Required fields are marked *