Demo 展示效果
從iOS7.0后蘋果自帶了側(cè)滑返回手勢功能
interactivePopGestureRecognizer
,但是有時我們自定義返回按鈕或者隱藏了導(dǎo)航欄,側(cè)滑返回就會失效,而它又是我們的應(yīng)用使用起來更加人性化必不可少的一部分,如何重現(xiàn)它呢?請往下看~
先看官方介紹
//The gesture recognizer responsible for popping the
top view controller off the navigation stack. (read-only)
The navigation controller installs this gesture
recognizer on its view and uses it to pop the topmost
view controller off the navigation stack. You can use
this property to retrieve the gesture recognizer and tie
it to the behavior of other gesture recognizers in your
user interface. When tying your gesture recognizers
together, make sure they recognize their gestures
simultaneously to ensure that your gesture recognizers
are given a chance to handle the event.
@property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
介紹和屬性中我們可以知道interactivePopGestureRecognizer
是負責(zé)把Navigation 棧中最上面的View Controller推出去。而且它只能在iOS7.0及以上可以使用,并且禁止在TVOS中使用柜与!
How to use
- 由于
interactivePopGestureRecognizer
是一種手勢,因此我們在使用它時需遵循UIGestureRecognizerDelegate
Protocol.
例如:
#import <UIKit/UIKit.h>
@interface ZHRootViewController : UIViewController<UIGestureRecognizerDelegate>
@end
- 我們需要把
interactivePopGestureRecognizer
使能打開,并設(shè)置委托對象,當(dāng)然在這之前別忘了對系統(tǒng)版本進行判斷,因為它只能在iOS7.0及以上使用咏删。
For example:
- (void)viewDidLoad
{
[super viewDidLoad];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
{
self.navigationController.interactivePopGestureRecognizer.enabled = YES; // 手勢有效設(shè)置為YES 無效為NO
self.navigationController.interactivePopGestureRecognizer.delegate = self; // 手勢的代理設(shè)置為self
}
// Do any additional setup after loading the view.
}
- 顯示或者隱藏NavigationBar 注意這里需要在函數(shù)
-(void)viewWillAppear:(BOOL)animated
中調(diào)用
Like this:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];//No 為顯示Navigationbar Yes 為隱藏
}
做完這些運行后動畫效果有了,是不是就完事了呢愕把?No No
- 你想一想如果已經(jīng)到Navigation 棧中最底一個Controller時我們還允許側(cè)滑么,顯然這時我們應(yīng)該使側(cè)滑手勢失效!
像這樣:
-(void)viewDidAppear:(BOOL)animated
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
{
if (self.navigationController.viewControllers.count==1) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
}
}
或者:
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if (self.navigationController.viewControllers.count == 1) {
return NO;
}else{
return YES;
}
}
到現(xiàn)在我們應(yīng)該做完了吧拣凹? No No
- 假如我們的View是一個可滑動的View呢?例如ScrollView,TableView,CollectionView恨豁。由于它們自帶了
panGestureRecognizer
所以它們一起使用時可能會產(chǎn)生沖突,如何避免呢嚣镜?我們可以設(shè)置一個手勢依賴關(guān)系!
Like this:
NSArray *gestureArray = self.navigationController.view.gestureRecognizers;//獲取所有的手勢
//當(dāng)是側(cè)滑手勢的時候設(shè)置panGestureRecognizer需要UIScreenEdgePanGestureRecognizer失效才生效即可
for (UIGestureRecognizer *gesture in gestureArray) {
if ([gesture isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
[self.tableView.panGestureRecognizer requireGestureRecognizerToFail:gesture];
}
}
這里你也許會疑惑為什么我們上面用的是UIScreenEdgePanGestureRecognizer
而不是interactivePopGestureRecognizer
橘蜜?
我們先打印self.navigationController.interactivePopGestureRecognizer
結(jié)果為:
<UIScreenEdgePanGestureRecognizer: 0x7f8283d31c90; state = Possible;
delaysTouchesBegan = YES;
view = <UILayoutContainerView 0x7f8283d2fae0>;
target= <(action=handleNavigationTransition:,
target=<_UINavigationInteractiveTransition 0x7f8283d31600>)>>
打印結(jié)果中我們看到了UIScreenEdgePanGestureRecognizer
:說明interactivePopGestureRecognizer
其實由UIScreenEdgePanGestureRecognizer
控制并執(zhí)行handleNavigationTransition:
其代理對象為_UINavigationInteractiveTransition
菊匿,所以判斷中我們使用了UIScreenEdgePanGestureRecognizer
.
擴展
我們可以根據(jù)UIScreenEdgePanGestureRecognizer
,handleNavigationTransition:
來自定義我們自己的側(cè)滑返回,這章先講訴到這里!
Demo
今天教師節(jié),祝天下所有教師:節(jié)日快樂!