SwipeBack ViewController trong Navigation
Bài đăng này đã không được cập nhật trong 6 năm
Làm thế nào để swipeback và detect action swipe của viewcontroller ở trong Navigation. Bởi default, khi add 1 viewcontroller vào Navigation thì chức năng swipe sẽ được tự động enable. Tuy nhiên, trong trường hợp mình custom nút back thì chức năng này sẽ bị disable. Vậy để có thể enable chức năng này, thì mình làm như sau:
InteractivePopGestureRecognizer
Để enable swipeback, đơn giản chỉ cần:
navigationController?.interactivePopGestureRecognizer?.delegate = self
navigationController?.interactivePopGestureRecognizer?.isEnabled = true
Tuy nhiên, để dễ dàng cho việc xử dụng, mình làm như sau: Tạo protocol VCInNavigation:
protocol VCInNavigation {
var numberVCInNav: Int? { get }
func delegateSwipeBack(of viewController: UIViewController?, to delegate: UIViewController?)
func enableSwipeBack(enable: Bool, for viewController: UIViewController?)
func viewWillSwipeBack()
}
- numberVCInNav : Số lượng viewcontrollers nằm trong Navigation stack
- delegateSwipeBack : chỉ định viewcontroller delegate
- enableSwipeBack : Enable/disable swipeback
- viewWillSwipeBack : Hàm detect sự kiện swipeback
Implement VCInNavigation protocol :
extension VCInNavigation where Self: UIViewController {
var numberVCInNav: Int? {
return self.navigationController?.viewControllers.count
}
func delegateSwipeBack(of viewController: UIViewController?, to delegate: UIViewController?) {
viewController?.navigationController?.interactivePopGestureRecognizer?.delegate = delegate
}
func enableSwipeBack(enable: Bool, for viewController: UIViewController?) {
viewController?.navigationController?.interactivePopGestureRecognizer?.isEnabled = enable
}
}
Detect swipeback action
Để detect được action khi swipeback viewcontroller, thì mình phải implement UIGestureRecognizerDelegate :
extension UIViewController: UIGestureRecognizerDelegate {
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
(self as? VCInNavigation)?.viewWillSwipeBack()
}
return true
}
}
- Đối với các controller thoả mãn VCInNavigation protocol thì viewWillSwipeBack mới đc call khi thực hiện action swipeback
Cách sử dụng
Đơn giản là chỉ cần adopt protocol VCInNavigation và thực hiện set delegate hay enable/disable swipeback là xong
class BaseViewController: UIViewController, VCInNavigation {
// MARK: - IBOutlet
// MARK: - Varialbes
// MARK: - View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// create back button
self.createBackButton()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// set delegate
self.delegateSwipeBack(of: self, to: self)
// enable/disable swipeback
if let count = self.numberVCInNav, count > 1 {
self.enableSwipeBack(enable: true, for: self)
} else {
self.enableSwipeBack(enable: false, for: self)
}
}
func viewWillSwipeBack() {
logD("\(String(describing: self))")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
deinit {
logD("\(String(describing: self))")
}
// MARK: - Setup View
// MARK: - Actions
// MARK: - Call Api
// MARK: - Functions
}
All rights reserved