我嘗試模擬Line Messenger應用程序(日本的事實上的Messenger軟件)中存在的行爲。iOS - 在關閉和滾動手勢之間切換
基本上,他們有一個內置滾動視圖的模式視圖控制器。當滾動操作到達其內容的頂部時,視圖控制器將無縫切換到交互式解除動畫。另外,當手勢將視圖返回到屏幕頂部時,控件將返回到滾動視圖。
下面是它的外觀。
對於我的生活,我想不通他們怎麼做。我嘗試了幾種不同的方法,但都失敗了,我沒有想法。任何人都可以將我指向正確的方向嗎?
EDIT2
爲了澄清,我想模仿不只是簡單地拖動窗口下的行爲。我可以那樣做,沒問題。
我想知道同一個滾動手勢(不用提起手指)如何觸發解除轉換,然後在視圖被拖回到原始位置後將控制轉移回滾動視圖。
這是我無法弄清楚的部分。
末EDIT2
EDIT1
這裏是我到目前爲止所。我能夠使用滾動視圖委託方法來添加處理常規解僱動畫的目標選擇器,但它仍然無法按預期工作。
我創建了一個UIViewController
作爲一個屬性UIWebView
。然後我把它放在一個UINavigationController
,這是模態地呈現。
導航控制器使用動畫/轉換控制器進行定期交互式解除(可以通過在導航欄上進行手勢操作來完成)。
從這裏,一切工作正常,但解僱不能從滾動視圖觸發。
NavigationController.h
@interface NavigationController : UINavigationController <UIViewControllerTransitioningDelegate>
@property (nonatomic, strong) UIPanGestureRecognizer *gestureRecog;
- (void)handleGesture:(UIPanGestureRecognizer*)gestureRecognizer;
@end
NavigationController.m
#import "NavigationController.h"
#import "AnimationController.h"
#import "TransitionController.h"
@implementation NavigationController {
AnimationController *_animator;
TransitionController *_interactor;
}
- (instancetype)init {
self = [super init];
self.transitioningDelegate = self;
_animator = [[AnimationController alloc] init];
_interactor = [[TransitionController alloc] init];
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Set the gesture recognizer
self.gestureRecog = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
[self.view addGestureRecognizer:_gestureRecog];
}
- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator {
if (animator == _animator && _interactor.hasStarted) {
return _interactor;
}
return nil;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
if (dismissed == self || [self.viewControllers indexOfObject:dismissed] != NSNotFound) {
return _animator;
}
return nil;
}
- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecog {
CGFloat threshold = 0.3f;
CGPoint translation = [gestureRecog translationInView:self.view];
CGFloat verticalMovement = translation.y/self.view.bounds.size.height;
CGFloat downwardMovement = fmaxf(verticalMovement, 0.0f);
CGFloat downwardMovementPercent = fminf(downwardMovement, 1.0f);
switch (gestureRecog.state) {
case UIGestureRecognizerStateBegan: {
_interactor.hasStarted = YES;
[self dismissViewControllerAnimated:YES completion:nil];
break;
}
case UIGestureRecognizerStateChanged: {
if (!_interactor.hasStarted) {
_interactor.hasStarted = YES;
[self dismissViewControllerAnimated:YES completion:nil];
}
_interactor.shouldFinish = downwardMovementPercent > threshold;
[_interactor updateInteractiveTransition:downwardMovementPercent];
break;
}
case UIGestureRecognizerStateCancelled: {
_interactor.hasStarted = NO;
[_interactor cancelInteractiveTransition];
break;
}
case UIGestureRecognizerStateEnded: {
_interactor.hasStarted = NO;
if (_interactor.shouldFinish) {
[_interactor finishInteractiveTransition];
} else {
[_interactor cancelInteractiveTransition];
}
break;
}
default: {
break;
}
}
}
@end
現在,我必須讓手勢操作時滾動視圖已經達到了頂級觸發。所以,這是我在視圖控制器中所做的。
WebViewController.m
#import "WebViewController.h"
#import "NavigationController.h"
@interface WebViewController()
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@end
@implementation WebViewController {
BOOL _isHandlingPan;
CGPoint _topContentOffset;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.webView.scrollView setDelegate:self];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if ((scrollView.panGestureRecognizer.state == UIGestureRecognizerStateBegan ||
scrollView.panGestureRecognizer.state == UIGestureRecognizerStateChanged) &&
! _isHandlingPan &&
scrollView.contentOffset.y < self.navigationController.navigationBar.translucent ? -64.0f : 0) {
NSLog(@"Adding scroll target");
_topContentOffset = CGPointMake(scrollView.contentOffset.x, self.navigationController.navigationBar.translucent ? -64.0f : 0);
_isHandlingPan = YES;
[scrollView.panGestureRecognizer addTarget:self action:@selector(handleGesture:)];
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
NSLog(@"Did End Dragging");
if (_isHandlingPan) {
NSLog(@"Removing action");
_isHandlingPan = NO;
[scrollView.panGestureRecognizer removeTarget:self action:@selector(handleGesture:)];
}
}
- (void)handleGesture:(UIPanGestureRecognizer*)gestureRecognizer {
[(NavigationController*)self.navigationController handleGesture:gestureRecognizer];
}
這仍然無法正常工作完全正確。即使在解散動畫期間,滾動視圖仍然隨着手勢滾動。
末EDIT1
你需要達成的滾動偏移值增加transitionViewController動畫ZFDragableModalTransition
圖像的源代碼。查看視圖控制器轉換的示例。 – iAviator