leftBarButtonItem을 설정 한 후 UINavigationController에서 뒤로 / 왼쪽 스 와이프 제스처를 활성화하는 방법은 무엇입니까?
나는 여기 에서 반대 문제를 얻었다 . 기본적으로 스택 iOS7
의 뒤로 스 와이프 제스처가 UINavigationController
표시 될 수 ViewController
있습니다. 이제 self.navigationItem.leftBarButtonItem
모든 ViewControllers
.
다음은 코드입니다.
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:LOADIMAGE(@"back_button") style:UIBarButtonItemStylePlain target:self action:@selector(popCurrentViewController)];
그 후에 navigationController.interactivePopGestureRecognizer
는 비활성화됩니다. 사용자 지정을 제거하지 않고 팝 제스처를 활성화하려면 어떻게 leftBarButtonItem
해야합니까?
감사!
viewDidLoad에서 첫 번째 대리자를 설정합니다.
self.navigationController.interactivePopGestureRecognizer.delegate = self;
그리고 푸시 할 때 제스처를 비활성화합니다.
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
[super pushViewController:viewController animated:animated];
self.interactivePopGestureRecognizer.enabled = NO;
}
그리고 viewDidDisappear에서 활성화하십시오.
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
또한 UINavigationControllerDelegate
뷰 컨트롤러에 추가 하십시오.
다음 두 가지 시나리오를 처리해야합니다.
- 스택에 새 뷰를 푸시 할 때
- 루트 뷰 컨트롤러를 표시 할 때
사용할 수있는 기본 클래스가 필요한 경우 Swift 3 버전이 있습니다.
import UIKit
final class SwipeNavigationController: UINavigationController {
// MARK: - Lifecycle
override init(rootViewController: UIViewController) {
super.init(rootViewController: rootViewController)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
delegate = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
delegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
// This needs to be in here, not in init
interactivePopGestureRecognizer?.delegate = self
}
deinit {
delegate = nil
interactivePopGestureRecognizer?.delegate = nil
}
// MARK: - Overrides
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
duringPushAnimation = true
super.pushViewController(viewController, animated: animated)
}
// MARK: - Private Properties
fileprivate var duringPushAnimation = false
}
// MARK: - UINavigationControllerDelegate
extension SwipeNavigationController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
guard let swipeNavigationController = navigationController as? SwipeNavigationController else { return }
swipeNavigationController.duringPushAnimation = false
}
}
// MARK: - UIGestureRecognizerDelegate
extension SwipeNavigationController: UIGestureRecognizerDelegate {
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
guard gestureRecognizer == interactivePopGestureRecognizer else {
return true // default value
}
// Disable pop gesture in two situations:
// 1) when the pop animation is in progress
// 2) when user swipes quickly a couple of times and animations don't have time to be performed
return viewControllers.count > 1 && duringPushAnimation == false
}
}
UINavigationControllerDelegate
다른 클래스에서 역할을해야하는 경우이 답변과 유사한 위임 전달자를 작성할 수 있습니다 .
Objective-C의 소스에서 수정 : https://github.com/fastred/AHKNavigationController
대리자를 설정할 때 효과적입니다.
self.navigationController.interactivePopGestureRecognizer.delegate = self;
다음 구현
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
그것은 나를 위해 작동합니다 Swift 3 :
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
그리고 ViewDidLoad에서 :
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
iOS 10, Swift 3 에서 스 와이프하여 팝업보기 컨트롤러를 활성화 / 비활성화하는 가장 좋은 방법입니다 .
첫 화면의 경우 [스 와이프 제스처를 비활성화하려는 위치] :
class SignUpViewController : UIViewController,UIGestureRecognizerDelegate {
//MARK: - View initializers
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
swipeToPop()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func swipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
self.navigationController?.interactivePopGestureRecognizer?.delegate = self;
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
return false
}
return true
} }
중간 화면의 경우 [스 와이프 제스처를 사용하려는 위치] :
class FriendListViewController : UIViewController {
//MARK: - View initializers
override func viewDidLoad() {
super.viewDidLoad()
swipeToPop()
}
func swipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil;
} }
스위프트 3 :
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return (otherGestureRecognizer is UIScreenEdgePanGestureRecognizer)
}
사용자 지정 뒤로 버튼을 설정하면 뒤로 스 와이프 기능이 비활성화됩니다.
The best thing to do to keep it is to subclass UINavigationViewController
and set itself as the interactivePopGestureRecognizer
delegate; then you can return YES from gestureRecognizerShouldBegin
to allow the swipe back.
For example, this is done in AHKNavigationController
And a Swift version here: https://stackoverflow.com/a/43433530/308315
This answer, but with storyboard support.
class SwipeNavigationController: UINavigationController {
// MARK: - Lifecycle
override init(rootViewController: UIViewController) {
super.init(rootViewController: rootViewController)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
private func setup() {
delegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
// This needs to be in here, not in init
interactivePopGestureRecognizer?.delegate = self
}
deinit {
delegate = nil
interactivePopGestureRecognizer?.delegate = nil
}
// MARK: - Overrides
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
duringPushAnimation = true
super.pushViewController(viewController, animated: animated)
}
// MARK: - Private Properties
fileprivate var duringPushAnimation = false
}
For those who are still having trouble with this, try separating the two lines as below.
override func viewDidLoad() {
self.navigationController!.interactivePopGestureRecognizer!.delegate = self
...
override func viewWillAppear(_ animated: Bool) {
self.navigationController!.interactivePopGestureRecognizer!.isEnabled = true
...
Obviously, in my app,
interactivePopGestureRecognizer!.isEnabled
got reset to false
before the view was shown for some reason.
'Program Tip' 카테고리의 다른 글
USB를 통해 앱 설치 : 장치가 일시적으로 제한됨 (0) | 2020.12.09 |
---|---|
TabLayout 탭 제목 텍스트 (소문자) (0) | 2020.12.09 |
NavigationView의 항목 텍스트 크기를 어떻게 변경할 수 있습니까? (0) | 2020.12.09 |
Go 프로그래밍 언어는 어떤 언어로 작성 되나요? (0) | 2020.12.09 |
객체 지향 언어의 HAS-A, IS-A 용어 (0) | 2020.12.09 |