Swift - 使用UIWebView和UIToolbar制作一个浏览器
(本文代码已升级至Swfit3)
使用网页控件(UIWebView)与工具栏控件(UIToolbar),我们可以自制一个小型的浏览器,其功能如下:

源代码下载:
hangge_550.zip
使用网页控件(UIWebView)与工具栏控件(UIToolbar),我们可以自制一个小型的浏览器,其功能如下:
1,输入网址,点击“Go”按钮加载网页
2,加载过程中有进度条,同时可以点击停止按钮取消加载
3,有页面刷新按钮
4,有前进后退按钮
效果图如下:

代码如下:
import UIKit class ViewController: UIViewController, UIWebViewDelegate, UITextFieldDelegate { @IBOutlet var btngo:UIButton! @IBOutlet var webview:UIWebView! @IBOutlet var txturl:UITextField! var loadIndicator:UIActivityIndicatorView! //进度条计时器 var ptimer:Timer! //进度条控件 var progBar:UIProgressView! override func viewDidLoad() { super.viewDidLoad() self.webview.delegate = self let frame = CGRect(x: 100.0, y: 100.0, width: 32.0, height: 32.0) loadIndicator = UIActivityIndicatorView(frame: frame) loadIndicator.activityIndicatorViewStyle = .gray self.view.addSubview(loadIndicator); txturl.delegate = self //构建浏览器工具条 setupBrowserToolbar() } func setupBrowserToolbar() { // 创建一个浏览器工具条,并设置它的大小和位置 let browserToolbar = UIToolbar(frame:CGRect(x: 0, y: 20, width: 320, height: 44)) // 将工具条添加到当前应用的界面中 self.view.addSubview(browserToolbar) //创建图片工具条,但是不是直接使用文件名,而是用 Data 方式初始化 UIImage let path = Bundle.main.path(forResource: "back", ofType:"png") let urlStr = URL(fileURLWithPath: path!); let data = try? Data(contentsOf: urlStr); let btnback = UIBarButtonItem(image:UIImage(data: data!), style:.plain, target:self, action:#selector(ViewController.backClicked(_:))); //第一个分隔按钮 let btngap1 = UIBarButtonItem(barButtonSystemItem:.flexibleSpace, target:nil, action:nil) // 创建前进按钮 UIBarButtonItem let btnforward = UIBarButtonItem(image:UIImage(named:"forward.png"), style:.plain, target:self, action:#selector(ViewController.forwardClicked(_:))) // 第二个分隔按钮,创建一个可伸缩的UIBarButtonItem let btngap2 = UIBarButtonItem(barButtonSystemItem:.flexibleSpace, target:nil, action:nil) // 创建重新加载按钮 UIBarButtonItem let btnreload = UIBarButtonItem(image:UIImage(named:"reload.png"), style:.plain, target:self, action:#selector(ViewController.reloadClicked(_:))) //第三个分隔按钮 let btngap3 = UIBarButtonItem(barButtonSystemItem:.flexibleSpace, target:nil, action:nil) //创建加载停止按钮 let btnstop = UIBarButtonItem(image:UIImage(named:"stop"), style:.plain, target:self, action:#selector(ViewController.stopClicked(_:))) //第四个分隔按钮 let btngap4 = UIBarButtonItem(barButtonSystemItem:.flexibleSpace, target:nil, action:nil) //创建进度工具条 progBar = UIProgressView(progressViewStyle:UIProgressViewStyle.bar) // 设置UIProgressView的大小 progBar.frame = CGRect(x: 0 , y: 0 , width: 80, height: 20) // 设置该进度条的初始进度为0 progBar.progress = 0 // 创建使用 UIView 的自定义的 UIBarButtonItem let btnprog = UIBarButtonItem(customView:progBar) // 为工具条设置工具按钮 browserToolbar.setItems( [btnback,btngap1,btnforward,btngap2,btnreload, btngap3,btnstop,btngap4, btnprog], animated:true) //创建计时器对象 ptimer = Timer.scheduledTimer(timeInterval: 0.2, target:self, selector: #selector(ViewController.loadProgress), userInfo:nil,repeats:true) ptimer.invalidate() } func textFieldShouldReturn(_ textField:UITextField) -> Bool { txturl.resignFirstResponder() print("url Changed!") let url = txturl.text; loadUrl(url!) return true } /* 在 UIWebView 加载指定 URL */ func loadUrl(_ url:String) { let urlobj = URL(string:url) let request = URLRequest(url:urlobj!) webview.loadRequest(request); } func stopClicked(_ sender:UIBarButtonItem) { webview.stopLoading() } func reloadClicked(_ sender:UIBarButtonItem) { webview.reload() } func backClicked(_ sender:UIBarButtonItem) { webview.goBack() } func forwardClicked(_ sender:UIBarButtonItem) { webview.goForward() } @IBAction func goClicked(_ sender:UIButton) { //收起输入面板 txturl.resignFirstResponder() let url = txturl.text; loadUrl(url!) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func webViewDidStartLoad(_ webView:UIWebView) { progBar.setProgress(0, animated:false); ptimer.fire(); loadIndicator.startAnimating(); } func webViewDidFinishLoad(_ webView:UIWebView) { loadIndicator.stopAnimating(); progBar.setProgress(1, animated:true); ptimer.invalidate(); } func loadProgress() { // 如果进度满了,停止计时器 if(progBar.progress >= 1.0) { // 停用计时器 ptimer.invalidate(); } else { // 改变进度条的进度值 progBar.setProgress(progBar.progress + 0.02, animated:true); } } func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { //999错误过滤(防止页面正在加载时候,点击stop按钮,提示NSURLErrorDomain error=-999) if error._code == NSURLErrorCancelled { return } let alertController = UIAlertController(title: "出错!", message: error.localizedDescription, preferredStyle: .alert) let okAction = UIAlertAction(title: "确定", style: .cancel, handler: nil) alertController.addAction(okAction) self.present(alertController, animated: true, completion: nil) } }
源代码下载:

航哥,我按照你的写了一遍,确实能用了,但是当一个页面正在加载时候,我点击stop按钮,会提示NSURLErrorDomain error=-999,我是用百度的网址测试的,请问这是为什么呢
大神 uiwebview 怎么加载证书不受信任的https网站啊 swift的
回复不可见???
不能添加评论
站长,能不能网址前不加http://和www
要是能把写每一部分代码的步骤也写上那就真是太完美了
航哥,这几天一直在折腾webview,想实现一些需求,网上找的资料也不尽如意,还是想给你留言,希望能得到你的帮助。
1、webview加载网页是,想在导航栏上显示网页的标题,一般都在webViewDidFinishLoad代理方法中加上语句:self.title = webView.stringByEvaluatingJavaScriptFromString("document.title") 但是,今天在测试一个网页的时候,刚一打开,在web view的代理方法didFailLoadWithError就报错,错误代码-999,而且webViewDidFinishLoad代理方法居然不会执行了!那此时我该如何去获取网页标题呢???我尝试性在这几个代理方法中打印webView.stringByEvaluatingJavaScriptFromString("document.title"),但是一直是空,但是我又在界面上加上一个测试按钮,触发事件也是打印这个值,却能打印出标题!真的好困惑!我的测试网址:http://politics.gmw.cn/2016-03/05/content_19181474.htm
2、我在你的那篇文章《Swift - 修改导航栏“返回”按钮文字,图标》下留了言,自定义按钮后右滑pop会消失。我看你已经更新解决了该问题:self.navigationController?.interactivePopGestureRecognizer!.delegate = self 这样做是能解决问题没错,但是我想做微信的加载webview的效果:在微信里打开个网页,点击网页里的链接,通过手势可以返回到上一个网页,当在第一个网页的时候,又可以手势pop当前的控制器。如果在打开的网页上再多次点击链接,默认情况下右滑直接pop回原VC,而不会一层一层地pop回上一级打开的网页,这种效果感觉挺难的没有一点思路,航哥能给点思路吗?谢谢!
楼主你写的博客我一直坚持再看, 请问下你在哪看的这些知识点
181行的UIAlertView();有警告说是ios9 deprecated 推荐使用一个新的类,新手也不太懂
swift前段时间刚刚改了,那啥println报错,直接写print()就行了吧,换行输出
楼主在吗?