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()就行了吧,换行输出
楼主在吗?