通常使用導航控制器 navigationController 跳轉到另一頁面時,除了可以點擊左上角的返回按鈕,還可以通過在屏幕左側向右滑動來返回到上一層。但如果自定義了 self.navigationItem.leftBarButtonItems 後會發現,滑動返回(swipe back)失效了。
(如何自定義導航欄左側按鈕可以看這篇文章:Swift - 修改導航欄“返回”按鈕文字,圖標)
1,讓滑動返回繼續有效
解決辦法是讓 ViewController 實現 UIGestureRecognizerDelegate 協議
import UIKit
class DetailViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
self.title = "hangge.com"
let button = UIButton(type: .System)
button.frame = CGRectMake(0, 0, 65, 30)
button.setImage(UIImage(named:"back"), forState: .Normal)
button.setTitle("返回", forState: .Normal)
button.addTarget(self, action: "backToPrevious", forControlEvents: .TouchUpInside)
let leftBarBtn = UIBarButtonItem(customView: button)
//用於消除左邊空隙,要不然按鈕頂不到最前面
let spacer = UIBarButtonItem(barButtonSystemItem: .FixedSpace, target: nil,
action: nil)
spacer.width = -10;
self.navigationItem.leftBarButtonItems = [spacer,leftBarBtn]
//啟用滑動返回(swipe back)
self.navigationController?.interactivePopGestureRecognizer!.delegate = self
}
//返回按鈕點擊響應
func backToPrevious(){
self.navigationController?.popViewControllerAnimated(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
注意:啟用滑動返回(swipe back)對當前 NavigationController 管理的所有 viewController 都有效。不需要每個 ViewController 都調用那個方法,我們只要保證它們在同一個 UINavigationController 裡即可。
2,與webview手勢沖突造成無法滑動返回
正常情況下通過上面的設置後就可以滑動返回了,但有時我們在頁面內放置了一個 webview 並加載網頁進來後,會發現滑動返回的功能又失效了。(webview如果沒加載頁面則沒有這個問題)
問題原因:由於 webview 加載的這個頁面自身內部需要用到手勢操作,或者 webview 放大之後需要一些滑動查看操作,於是便造成事件沖突。
解決辦法:新建了一個 tap手勢,設置代理,同時實現允許多個手勢並發的代理方法
import UIKit
class DetailViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
self.title = "hangge.com"
let urlobj = NSURL(string:"http://www.hangge.com")
let request = NSURLRequest(URL:urlobj!)
webView.loadRequest(request);
let button = UIButton(type: .System)
button.frame = CGRectMake(0, 0, 65, 30)
button.setImage(UIImage(named:"back"), forState: .Normal)
button.setTitle("返回", forState: .Normal)
button.addTarget(self, action: "backToPrevious", forControlEvents: .TouchUpInside)
let leftBarBtn = UIBarButtonItem(customView: button)
//用於消除左邊空隙,要不然按鈕頂不到最前面
let spacer = UIBarButtonItem(barButtonSystemItem: .FixedSpace, target: nil,
action: nil)
spacer.width = -10;
self.navigationItem.leftBarButtonItems = [spacer,leftBarBtn]
//啟用滑動返回(swipe back)
self.navigationController?.interactivePopGestureRecognizer!.delegate = self
//新建一個滑動手勢
let tap = UISwipeGestureRecognizer(target:self, action:nil)
tap.delegate = self
self.webView.addGestureRecognizer(tap)
}
//返回true表示所有相同類型的手勢辨認都會得到處理
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer:
UIGestureRecognizer) -> Bool {
return true
}
//返回按鈕點擊響應
func backToPrevious(){
self.navigationController?.popViewControllerAnimated(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
原文出自:www.hangge.com