Skip to content

Commit

Permalink
手势控制贝塞尔曲线
Browse files Browse the repository at this point in the history
  • Loading branch information
BigShow1949 committed Aug 24, 2016
1 parent 4bae789 commit 84c9ad7
Show file tree
Hide file tree
Showing 8 changed files with 326 additions and 3 deletions.
Binary file modified .svn/wc.db
Binary file not shown.
20 changes: 20 additions & 0 deletions BigShow1949.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
185C99311D67F0A500955C5F /* YFScrollViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 185C99071D67F0A500955C5F /* YFScrollViewController.m */; };
185C99321D67F0A500955C5F /* SearchResultsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 185C990A1D67F0A500955C5F /* SearchResultsViewController.m */; };
185C99331D67F0A500955C5F /* YFSearchController.m in Sources */ = {isa = PBXBuildFile; fileRef = 185C990C1D67F0A500955C5F /* YFSearchController.m */; };
186324CE1D6C591800BD5835 /* YFBounceViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 186324CD1D6C591800BD5835 /* YFBounceViewController.m */; };
186324D21D6C597900BD5835 /* BounceView.m in Sources */ = {isa = PBXBuildFile; fileRef = 186324D11D6C597900BD5835 /* BounceView.m */; };
189242651B99D065008AC1EB /* YFAuthorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 189242641B99D065008AC1EB /* YFAuthorViewController.m */; };
18C2D5331BAEDC98006CD3B2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18C2D5311BAEDC61006CD3B2 /* UIKit.framework */; };
18C2D5361BAEDCC8006CD3B2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18C2D5341BAEDCAC006CD3B2 /* Foundation.framework */; };
Expand Down Expand Up @@ -665,6 +667,10 @@
185C990A1D67F0A500955C5F /* SearchResultsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SearchResultsViewController.m; sourceTree = "<group>"; };
185C990B1D67F0A500955C5F /* YFSearchController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YFSearchController.h; sourceTree = "<group>"; };
185C990C1D67F0A500955C5F /* YFSearchController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YFSearchController.m; sourceTree = "<group>"; };
186324CC1D6C591800BD5835 /* YFBounceViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YFBounceViewController.h; path = ../../YFBounceViewController.h; sourceTree = "<group>"; };
186324CD1D6C591800BD5835 /* YFBounceViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YFBounceViewController.m; path = ../../YFBounceViewController.m; sourceTree = "<group>"; };
186324D01D6C597900BD5835 /* BounceView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BounceView.h; sourceTree = "<group>"; };
186324D11D6C597900BD5835 /* BounceView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BounceView.m; sourceTree = "<group>"; };
189242631B99D065008AC1EB /* YFAuthorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YFAuthorViewController.h; sourceTree = "<group>"; };
189242641B99D065008AC1EB /* YFAuthorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = YFAuthorViewController.m; sourceTree = "<group>"; };
18C2D5311BAEDC61006CD3B2 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -1899,6 +1905,17 @@
path = UISearchController;
sourceTree = "<group>";
};
186324CF1D6C596900BD5835 /* 手势控制贝塞尔曲线 */ = {
isa = PBXGroup;
children = (
186324CC1D6C591800BD5835 /* YFBounceViewController.h */,
186324CD1D6C591800BD5835 /* YFBounceViewController.m */,
186324D01D6C597900BD5835 /* BounceView.h */,
186324D11D6C597900BD5835 /* BounceView.m */,
);
path = "手势控制贝塞尔曲线";
sourceTree = "<group>";
};
18C2D52F1BAEDC2C006CD3B2 /* Framework */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3137,6 +3154,7 @@
children = (
B87300811C50742800090C9D /* YFBezierViewController.h */,
B87300821C50742800090C9D /* YFBezierViewController.m */,
186324CF1D6C596900BD5835 /* 手势控制贝塞尔曲线 */,
180017DB1D6C50BA001CC8C8 /* 加载框 */,
185C98A51D67E6EC00955C5F /* 仿支付宝余额跳动 */,
B87300881C50807200090C9D /* 02 - 渐变色 */,
Expand Down Expand Up @@ -4295,6 +4313,7 @@
18C760EF1B9AD4300038B2EE /* YFRecordData.m in Sources */,
B852D5371C51F8A600454E7F /* YFPushTransitionViewController.m in Sources */,
B891DAF01CA11ABB007F69AF /* View+MASAdditions.m in Sources */,
186324CE1D6C591800BD5835 /* YFBounceViewController.m in Sources */,
B891DB281CA1300D007F69AF /* PFGoldenSectionSpiral.m in Sources */,
B870425F1CAB7CEB0067653C /* YFAnswerViewController.m in Sources */,
18C75C721B9AA77B0038B2EE /* SYEmotionButton.m in Sources */,
Expand Down Expand Up @@ -4331,6 +4350,7 @@
B891DB051CA124AF007F69AF /* YFTagsCloudViewController.m in Sources */,
B88A15481CA393F400BFC377 /* Case1ViewController.m in Sources */,
18CAD0D71B998F92001066FF /* YFEmitterRainCell.m in Sources */,
186324D21D6C597900BD5835 /* BounceView.m in Sources */,
B814BD191CE029780024096A /* HWLineLayout.m in Sources */,
B852D51C1C51D60800454E7F /* CABasicAnimationViewController.m in Sources */,
B814BD091CE028CB0024096A /* YFHorizontalScrollViewController.m in Sources */,
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ - (void)viewDidLoad {
self.titles = @[@"动态圆圈",
@"渐变色",
@"仿支付宝余额跳动",
@"加载框"];
@"加载框",
@"手势控制贝塞尔曲线"];

self.classNames = @[@"YFCircleViewController",
@"YFGradientViewController",
@"YFAliNumberViewController",
@"YFCircleLoaderViewController"];
@"YFCircleLoaderViewController",
@"YFBounceViewController"];
}




@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//
// BounceView.h
// KYBezierBounceView
//
// Created by Kitten Yang on 2/17/15.
// Copyright (c) 2015 Kitten Yang. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface BounceView : UIView

@property(nonatomic,strong)CAShapeLayer * verticalLineLayer;
@property(nonatomic,strong)UIPanGestureRecognizer *sgr;

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
//
// BounceView.m
// KYBezierBounceView
//
// Created by Kitten Yang on 2/17/15.
// Copyright (c) 2015 Kitten Yang. All rights reserved.
//

#import "BounceView.h"

@implementation BounceView{
UIView *leftBubble;
UIView *righBubble;
}


-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
[self createLine];
[self addPanGesture];
}
return self;
}


-(id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self createLine];
[self addPanGesture];
}
return self;
}


- (void) createLine {
self.verticalLineLayer = [CAShapeLayer layer];
self.verticalLineLayer.strokeColor = [[UIColor whiteColor] CGColor];
self.verticalLineLayer.lineWidth = 1.0;
self.verticalLineLayer.fillColor = [[UIColor whiteColor] CGColor];

[self.layer addSublayer:self.verticalLineLayer];
}


- (void) addPanGesture {
self.sgr = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleSlide:)];
[self addGestureRecognizer:self.sgr];
}



//左边曲线
- (CGPathRef) getLeftLinePathWithAmount:(CGFloat)amount {
UIBezierPath *verticalLine = [UIBezierPath bezierPath];
CGPoint topPoint = CGPointMake(0, 0);
CGPoint midControlPoint = CGPointMake(amount, self.bounds.size.height/2);
CGPoint bottomPoint = CGPointMake(0, self.bounds.size.height);

[verticalLine moveToPoint:topPoint];
[verticalLine addQuadCurveToPoint:bottomPoint controlPoint:midControlPoint];
[verticalLine closePath];

return [verticalLine CGPath];
}

//右边曲线
-(CGPathRef) getRightLinePathWithAmount:(CGFloat)amount{
UIBezierPath *verticalLine = [UIBezierPath bezierPath];
CGPoint topPoint = CGPointMake(self.bounds.size.width , 0);
CGPoint midControlPoint = CGPointMake(self.bounds.size.width - amount, self.bounds.size.height/2);
CGPoint bottomPoint = CGPointMake(self.bounds.size.width , self.bounds.size.height);

[verticalLine moveToPoint:topPoint];
[verticalLine addQuadCurveToPoint:bottomPoint controlPoint:midControlPoint];
[verticalLine closePath];

return [verticalLine CGPath];
}


- (void) handleSlide:(UIPanGestureRecognizer *)gr{
CGFloat amountX = [gr translationInView:self].x;
CGFloat amountY = [gr translationInView:self].y;


if ( ABS(amountY) > ABS(amountX)) {

[self cancelPost];
[self cancelComment];
return;
}



if (gr.state == UIGestureRecognizerStateChanged){
if (amountX >= 0) {

if (leftBubble == nil) {
leftBubble = [[UIView alloc]init];
leftBubble.center = CGPointMake(-100, self.bounds.size.height / 2);
leftBubble.bounds = CGRectMake(0, 0, 100, 100);
leftBubble.backgroundColor = [UIColor redColor];
leftBubble.layer.cornerRadius = 50;
[self addSubview:leftBubble];
}

//向右滑 ———— 转发
[self cancelComment];
self.verticalLineLayer.path = [self getLeftLinePathWithAmount:amountX];
leftBubble.frame = CGRectMake(-100 + amountX*0.4, leftBubble.frame.origin.y, 100, 100);
if (amountX > self.bounds.size.width / 2) {
[UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.6f initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
leftBubble.center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
} completion:^(BOOL finished) {
[self cancelPost];
}];
[self removeGestureRecognizer:gr];
[self animateLeftLineReturnFrom:amountX];
}
}else{
if (righBubble == nil) {
righBubble = [[UIView alloc]init];
righBubble.center = CGPointMake(self.bounds.size.width + 100, self.bounds.size.height / 2);
righBubble.bounds = CGRectMake(0, 0, 100, 100);
righBubble.backgroundColor = [UIColor blueColor];
righBubble.layer.cornerRadius = 50;
[self addSubview:righBubble];
}

//向左滑 ———— 评论
[self cancelPost];
self.verticalLineLayer.path = [self getRightLinePathWithAmount:fabs(amountX)];
righBubble.frame = CGRectMake(self.bounds.size.width + amountX*0.4, righBubble.frame.origin.y, 100, 100);
if (fabs(amountX) > self.bounds.size.width / 2) {

[UIView animateWithDuration:0.5f delay:0.0f usingSpringWithDamping:0.6f initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
righBubble.center = CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2);
} completion:^(BOOL finished) {
[self cancelComment];
}];

[self removeGestureRecognizer:gr];
[self animateRightLineReturnFrom:fabs(amountX)];
}
}
}

if (gr.state == UIGestureRecognizerStateEnded || gr.state == UIGestureRecognizerStateCancelled || gr.state == UIGestureRecognizerStateFailed) {
[self cancelPost];
[self cancelComment];
if (amountX >= 0) {
[self removeGestureRecognizer:gr];
[self animateLeftLineReturnFrom:amountX];
}else{
[self removeGestureRecognizer:gr];
[self animateRightLineReturnFrom:fabs(amountX)];
}
}
}

-(void)cancelPost{

[UIView animateWithDuration:0.8f delay:0.0f usingSpringWithDamping:0.6f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
leftBubble.center = CGPointMake(-100, self.bounds.size.height / 2);
} completion:^(BOOL finished) {
[leftBubble removeFromSuperview];
leftBubble = nil;
}];
}

-(void)cancelComment{

[UIView animateWithDuration:0.8f delay:0.0f usingSpringWithDamping:0.6f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
righBubble.center = CGPointMake(self.bounds.size.width + 100, self.bounds.size.height / 2);
} completion:^(BOOL finished) {
[righBubble removeFromSuperview];
righBubble = nil;
}];
}

- (void) animateLeftLineReturnFrom:(CGFloat)positionX {
// ----- ANIMATION WITH BOUNCE
CAKeyframeAnimation *morph = [CAKeyframeAnimation animationWithKeyPath:@"path"];
morph.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
NSArray *values = @[
(id) [self getLeftLinePathWithAmount:positionX],
(id) [self getLeftLinePathWithAmount:-(positionX * 0.9)],
(id) [self getLeftLinePathWithAmount:(positionX * 0.6)],
(id) [self getLeftLinePathWithAmount:-(positionX * 0.4)],
(id) [self getLeftLinePathWithAmount:(positionX * 0.25)],
(id) [self getLeftLinePathWithAmount:-(positionX * 0.15)],
(id) [self getLeftLinePathWithAmount:(positionX * 0.05)],
(id) [self getLeftLinePathWithAmount:0.0]
];
morph.values = values;
morph.duration = 0.5;
morph.removedOnCompletion = NO;
morph.fillMode = kCAFillModeForwards;
morph.delegate = self;
[self.verticalLineLayer addAnimation:morph forKey:@"bounce_left"];

}

- (void) animateRightLineReturnFrom:(CGFloat)positionX {
// ----- ANIMATION WITH BOUNCE
CAKeyframeAnimation *morph = [CAKeyframeAnimation animationWithKeyPath:@"path"];
morph.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
NSArray *values = @[
(id) [self getRightLinePathWithAmount:positionX],
(id) [self getRightLinePathWithAmount:-(positionX * 0.9)],
(id) [self getRightLinePathWithAmount:(positionX * 0.6)],
(id) [self getRightLinePathWithAmount:-(positionX * 0.4)],
(id) [self getRightLinePathWithAmount:(positionX * 0.25)],
(id) [self getRightLinePathWithAmount:-(positionX * 0.15)],
(id) [self getRightLinePathWithAmount:(positionX * 0.05)],
(id) [self getRightLinePathWithAmount:0.0]
];
morph.values = values;
morph.duration = 0.5;
morph.removedOnCompletion = NO;
morph.fillMode = kCAFillModeForwards;
morph.delegate = self;
[self.verticalLineLayer addAnimation:morph forKey:@"bounce_right"];
}



#pragma mark - CAAnimationDelegate
- (void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if (anim == [self.verticalLineLayer animationForKey:@"bounce_left"] ) {
self.verticalLineLayer.path = [self getLeftLinePathWithAmount:0.0];
[self.verticalLineLayer removeAllAnimations];
[self addPanGesture];
}else if(anim == [self.verticalLineLayer animationForKey:@"bounce_right"]){
self.verticalLineLayer.path = [self getRightLinePathWithAmount:0.0];
[self.verticalLineLayer removeAllAnimations];
[self addPanGesture];
}
}

@end
13 changes: 13 additions & 0 deletions BigShow1949/Classes/Animations/YFBounceViewController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// YFBounceViewController.h
// BigShow1949
//
// Created by apple on 16/8/23.
// Copyright © 2016年 BigShowCompany. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface YFBounceViewController : UIViewController

@end
30 changes: 30 additions & 0 deletions BigShow1949/Classes/Animations/YFBounceViewController.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// YFBounceViewController.m
// BigShow1949
//
// Created by apple on 16/8/23.
// Copyright © 2016年 BigShowCompany. All rights reserved.
//

#import "YFBounceViewController.h"
#import "BounceView.h"
@interface YFBounceViewController ()

@end

@implementation YFBounceViewController

- (void)viewDidLoad {
[super viewDidLoad];

self.view.backgroundColor = [UIColor blueColor];

BounceView *view = [[BounceView alloc] init];
view.backgroundColor = [UIColor lightGrayColor];
view.frame = self.view.bounds;
[self.view addSubview:view];

}


@end

0 comments on commit 84c9ad7

Please sign in to comment.