Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
zhxnlai committed Oct 26, 2015
1 parent 8e9ce9e commit dbc0856
Show file tree
Hide file tree
Showing 22 changed files with 1,237 additions and 538 deletions.
14 changes: 14 additions & 0 deletions ZLSwipeableView/DefaultDirectionInterpretor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// DefaultDirectionInterpretor.h
// ZLSwipeableViewDemo
//
// Created by Zhixuan Lai on 10/25/15.
// Copyright © 2015 Zhixuan Lai. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ZLSwipeableView.h"

@interface DefaultDirectionInterpretor : NSObject <ZLSwipeableViewDirectionInterpretor>

@end
42 changes: 42 additions & 0 deletions ZLSwipeableView/DefaultDirectionInterpretor.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// DefaultDirectionInterpretor.m
// ZLSwipeableViewDemo
//
// Created by Zhixuan Lai on 10/25/15.
// Copyright © 2015 Zhixuan Lai. All rights reserved.
//

#import "DefaultDirectionInterpretor.h"

@implementation DefaultDirectionInterpretor

- (ZLSwipeableViewSwipeOptions *)interpretDirection:(ZLSwipeableViewDirection)direction
view:(UIView *)view
index:(NSUInteger)index
views:(NSArray<UIView *> *)views
swipeableView:(ZLSwipeableView *)swipeableView {
CGFloat programaticSwipeVelocity = 1000;
CGPoint location = CGPointMake(view.center.x, view.center.y * 0.7);
CGVector directionVector;
switch (direction) {
case ZLSwipeableViewDirectionLeft:
directionVector = CGVectorMake(-programaticSwipeVelocity, 0);
break;
case ZLSwipeableViewDirectionRight:
directionVector = CGVectorMake(programaticSwipeVelocity, 0);
break;
case ZLSwipeableViewDirectionUp:
directionVector = CGVectorMake(0, -programaticSwipeVelocity);
break;
case ZLSwipeableViewDirectionDown:
directionVector = CGVectorMake(0, programaticSwipeVelocity);
break;
default:
directionVector = CGVectorMake(0, 0);
break;
}
return
[[ZLSwipeableViewSwipeOptions alloc] initWithLocation:location direction:directionVector];
}

@end
14 changes: 14 additions & 0 deletions ZLSwipeableView/DefaultShouldSwipeDeterminator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// DefaultShouldSwipeDeterminator.h
// ZLSwipeableViewDemo
//
// Created by Zhixuan Lai on 10/25/15.
// Copyright © 2015 Zhixuan Lai. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ZLSwipeableView.h"

@interface DefaultShouldSwipeDeterminator : NSObject <ZLSwipeableViewSwipingDeterminator>

@end
57 changes: 57 additions & 0 deletions ZLSwipeableView/DefaultShouldSwipeDeterminator.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// DefaultShouldSwipeDeterminator.m
// ZLSwipeableViewDemo
//
// Created by Zhixuan Lai on 10/25/15.
// Copyright © 2015 Zhixuan Lai. All rights reserved.
//

#import "DefaultShouldSwipeDeterminator.h"
#import "Utils.h"

@implementation DefaultShouldSwipeDeterminator

- (BOOL)shouldSwipeView:(UIView *)view
movement:(ZLSwipeableViewMovement *)movement
swipeableView:(ZLSwipeableView *)swipeableView {
CGPoint translation = movement.translation;
CGPoint velocity = movement.velocity;
CGRect bounds = swipeableView.bounds;
CGFloat minTranslationInPercent = swipeableView.minTranslationInPercent;
CGFloat minVelocityInPointPerSecond = swipeableView.minVelocityInPointPerSecond;
CGFloat allowedDirection = swipeableView.allowedDirection;

return [self isDirectionAllowed:translation allowedDirection:allowedDirection] &&
[self isTranslation:translation inTheSameDirectionWithVelocity:velocity] &&
([self isTranslationLargeEnough:translation
minTranslationInPercent:minTranslationInPercent
bounds:bounds] ||
[self isVelocityLargeEnough:velocity
minVelocityInPointPerSecond:minVelocityInPointPerSecond]);
}

- (BOOL)isTranslation:(CGPoint)p1 inTheSameDirectionWithVelocity:(CGPoint)p2 {
return signNum(p1.x) == signNum(p2.x) && signNum(p1.y) == signNum(p2.y);
}

- (BOOL)isDirectionAllowed:(CGPoint)translation
allowedDirection:(ZLSwipeableViewDirection)allowedDirection {
return (ZLSwipeableViewDirectionFromPoint(translation) & allowedDirection) !=
ZLSwipeableViewDirectionNone;
}

- (BOOL)isTranslationLargeEnough:(CGPoint)translation
minTranslationInPercent:(CGFloat)minTranslationInPercent
bounds:(CGRect)bounds {
return ABS(translation.x) > minTranslationInPercent * bounds.size.width ||
ABS(translation.y) > minTranslationInPercent * bounds.size.height;
}

- (BOOL)isVelocityLargeEnough:(CGPoint)velocity
minVelocityInPointPerSecond:(CGFloat)minVelocityInPointPerSecond {
return CGPointMagnitude(velocity) > minVelocityInPointPerSecond;
}

int signNum(CGFloat n) { return (n < 0) ? -1 : (n > 0) ? +1 : 0; }

@end
51 changes: 51 additions & 0 deletions ZLSwipeableView/DefaultViewAnimator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// DefaultViewAnimator.h
// ZLSwipeableViewDemo
//
// Created by Zhixuan Lai on 10/25/15.
// Copyright © 2015 Zhixuan Lai. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ZLSwipeableView.h"

@interface DefaultViewAnimator : NSObject <ZLSwipeableViewAnimator>

// self.isRotationEnabled = YES;
// self.rotationDegree = 1;
// self.rotationRelativeYOffsetFromCenter = 0.3;
// self.programaticSwipeRotationRelativeYOffsetFromCenter = -0.2;

/*
/// Enable this to rotate the views behind the top view. Default to `YES`.
@property (nonatomic) BOOL isRotationEnabled;
/// Magnitude of the rotation in degrees
@property (nonatomic) float rotationDegree;
/// Relative vertical offset of the center of rotation. From 0 to 1. Default to
/// 0.3.
@property (nonatomic) float rotationRelativeYOffsetFromCenter;
/// Enable this to allow swiping left and right. Default to
/// `ZLSwipeableViewDirectionBoth`.
@property (nonatomic) ZLSwipeableViewDirection direction;
/// Magnitude in points per second.
@property (nonatomic) CGFloat escapeVelocityThreshold;
/// The relative distance from center that will
@property (nonatomic) CGFloat relativeTranslationThreshold;
/// Magnitude of velocity at which the swiped view will be animated.
@property (nonatomic) CGFloat pushVelocityMagnitude;
/// Swiped views will be destroyed when they collide with this rect.
@property (nonatomic) CGRect collisionRect;
/// Relative vertical offset of the center of rotation for swiping views
/// programatically.
@property (nonatomic) CGFloat programaticSwipeRotationRelativeYOffsetFromCenter;
*/

@end
128 changes: 128 additions & 0 deletions ZLSwipeableView/DefaultViewAnimator.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
//
// DefaultViewAnimator.m
// ZLSwipeableViewDemo
//
// Created by Zhixuan Lai on 10/25/15.
// Copyright © 2015 Zhixuan Lai. All rights reserved.
//

#import "DefaultViewAnimator.h"

@implementation DefaultViewAnimator

- (CGFloat)degreesToRadians:(CGFloat)degrees {
return degrees * M_PI / 180;
}

- (CGFloat)radiansToDegrees:(CGFloat)radians {
return radians * 180 / M_PI;
}

- (void)rotateView:(UIView *)view
forDegree:(float)degree
duration:(NSTimeInterval)duration
atOffsetFromCenter:(CGPoint)offset
swipeableView:(ZLSwipeableView *)swipeableView {
float rotationRadian = [self degreesToRadians:degree];
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionAllowUserInteraction
animations:^{
view.center = [swipeableView convertPoint:swipeableView.center
fromView:swipeableView.superview];
CGAffineTransform transform =
CGAffineTransformMakeTranslation(offset.x, offset.y);
transform = CGAffineTransformRotate(transform, rotationRadian);
transform = CGAffineTransformTranslate(transform, -offset.x, -offset.y);
view.transform = transform;
}
completion:nil];
}

- (void)animateView:(UIView *)view
index:(NSUInteger)index
views:(NSArray<UIView *> *)views
swipeableView:(ZLSwipeableView *)swipeableView {
CGFloat degree = 1;
NSTimeInterval duration = 0.4;
CGPoint offset = CGPointMake(0, CGRectGetHeight(swipeableView.bounds) * 0.3);
switch (index) {
case 0:
[self rotateView:view
forDegree:0
duration:duration
atOffsetFromCenter:offset
swipeableView:swipeableView];
break;
case 1:
[self rotateView:view
forDegree:degree
duration:duration
atOffsetFromCenter:offset
swipeableView:swipeableView];
break;
case 2:
[self rotateView:view
forDegree:-degree
duration:duration
atOffsetFromCenter:offset
swipeableView:swipeableView];
break;
case 3:
[self rotateView:view
forDegree:0
duration:duration
atOffsetFromCenter:offset
swipeableView:swipeableView];
break;
default:
break;
}
}
/*
- (void)animateSwipeableViewsIfNeeded {
UIView *topSwipeableView = self.topSwipeableView;
if (!topSwipeableView) {
return;
}
for (UIView *cover in self.containerView.subviews) {
cover.userInteractionEnabled = NO;
}
topSwipeableView.userInteractionEnabled = YES;
for (UIGestureRecognizer *recognizer in topSwipeableView.gestureRecognizers) {
if (recognizer.state != UIGestureRecognizerStatePossible) {
return;
}
}
if (self.isRotationEnabled) {
// rotation
NSUInteger numSwipeableViews = self.containerView.subviews.count;
if (numSwipeableViews >= 1) {
[self.animator removeBehavior:self.swipeableViewSnapBehavior];
self.swipeableViewSnapBehavior = [self
snapBehaviorThatSnapView:self.containerView.subviews[numSwipeableViews - 1]
toPoint:[self convertPoint:self.center fromView:self.superview]];
[self.animator addBehavior:self.swipeableViewSnapBehavior];
}
CGPoint rotationCenterOffset = {0, CGRectGetHeight(topSwipeableView.frame) *
self.rotationRelativeYOffsetFromCenter};
if (numSwipeableViews >= 2) {
[self rotateView:self.containerView.subviews[numSwipeableViews - 2]
forDegree:self.rotationDegree
atOffsetFromCenter:rotationCenterOffset
animated:YES];
}
if (numSwipeableViews >= 3) {
[self rotateView:self.containerView.subviews[numSwipeableViews - 3]
forDegree:-self.rotationDegree
atOffsetFromCenter:rotationCenterOffset
animated:YES];
}
}
}
*/
@end
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

#import <UIKit/UIKit.h>

@interface ZLPanGestureRecognizer : UIPanGestureRecognizer
@interface PanGestureRecognizer : UIPanGestureRecognizer

@end
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
// Copyright (c) 2014 Zhixuan Lai. All rights reserved.
//

#import "ZLPanGestureRecognizer.h"
#import "PanGestureRecognizer.h"

@implementation ZLPanGestureRecognizer
@implementation PanGestureRecognizer

@end
24 changes: 24 additions & 0 deletions ZLSwipeableView/Scheduler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// Scheduler.h
// ZLSwipeableViewDemo
//
// Created by Zhixuan Lai on 10/25/15.
// Copyright © 2015 Zhixuan Lai. All rights reserved.
//

#import <Foundation/Foundation.h>

typedef void (^Action)(void);
typedef BOOL (^EndCondition)(void);

@interface Scheduler : NSObject

@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) Action action;
@property (nonatomic, strong) EndCondition endCondition;

- (void)scheduleActionRepeatedly:(Action)action
interval:(NSTimeInterval)interval
endCondition:(EndCondition)endCondition;

@end
39 changes: 39 additions & 0 deletions ZLSwipeableView/Scheduler.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// Scheduler.m
// ZLSwipeableViewDemo
//
// Created by Zhixuan Lai on 10/25/15.
// Copyright © 2015 Zhixuan Lai. All rights reserved.
//

#import "Scheduler.h"

@implementation Scheduler

- (void)scheduleActionRepeatedly:(Action)action
interval:(NSTimeInterval)interval
endCondition:(EndCondition)endCondition {
if (self.timer != nil || interval <= 0) {
return;
}

self.action = action;
self.endCondition = endCondition;
self.timer = [NSTimer scheduledTimerWithTimeInterval:interval
target:self
selector:@selector(doAction)
userInfo:nil
repeats:YES];
}

- (void)doAction {
if (!self.action || !self.endCondition || self.endCondition()) {
[self.timer invalidate];
self.timer = nil;
return;
}

self.action();
}

@end
Loading

0 comments on commit dbc0856

Please sign in to comment.