这里用pan手势实现旋转功能
- 新建New->File->Cocoa Touch Class
- .h文件继承手势类UIGestureRecognizer
#import <UIKit/UIKit.h>
@interface KTOneFingerRotationGestureRecognizer : UIGestureRecognizer
{
}
/**
The rotation of the gesture in radians since its last change.
*/
@property (nonatomic, assign) CGFloat rotation;
@end
接下来我会分析UIGestureRecognizer:UIGestureRecognizer.h分析
最重要的是它的子类UIGestureRecognizerSubclass.h:UIGestureRecognizerSubclass.h分析
- .m文件实现手势方法
#import "KTOneFingerRotationGestureRecognizer.h"//非常重要引用这个类
#import <UIKit/UIGestureRecognizerSubclass.h>
@implementation KTOneFingerRotationGestureRecognizer
@synthesize rotation = rotation_;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// Fail when more than 1 finger detected.
if ([[event touchesForGestureRecognizer:self] count] > 1) {
[self setState:UIGestureRecognizerStateFailed];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
//UIGestureRecognizerStatePossible:The gesture recognizer has not
//yet recognized its gesture, but may be evaluating touch events.
//This is the default state.
if ([self state] == UIGestureRecognizerStatePossible) {
[self setState:UIGestureRecognizerStateBegan];
} else {
[self setState:UIGestureRecognizerStateChanged];
}
// We can look at any touch object since we know we
// have only 1. If there were more than 1 then
// touchesBegan:withEvent: would have failed the recognizer.
UITouch *touch = [touches anyObject];
// To rotate with one finger, we simulate a second finger.
// The second figure is on the opposite side of the virtual
// circle that represents the rotation gesture.
UIView *view = [self view];
CGPoint center = CGPointMake(CGRectGetMidX([view bounds]), CGRectGetMidY([view bounds]));
CGPoint currentTouchPoint = [touch locationInView:view];//找到触碰点在视图中位置
CGPoint previousTouchPoint = [touch previousLocationInView:view];//上一个触碰点在视图位置
//反正切:范围在-pi/2~pi/2,因此可以分出顺逆时针
//看流程图:可以得到现在点的正切角-上一个点的正切角等于旋转后的角度
CGFloat angleInRadians = atan2f(currentTouchPoint.y - center.y, currentTouchPoint.x - center.x) - atan2f(previousTouchPoint.y - center.y, previousTouchPoint.x - center.x);
[self setRotation:angleInRadians];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// Perform final check to make sure a tap was not misinterpreted.
if ([self state] == UIGestureRecognizerStateChanged) {
[self setState:UIGestureRecognizerStateEnded];
} else {
[self setState:UIGestureRecognizerStateFailed];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[self setState:UIGestureRecognizerStateFailed];
}
@end

- 实现思路

(1)关闭右下角按钮的互动:
self.zoomButton.userInteractionEnabled = NO;//是否开启用户事件
(2)用masonry自动布局沿着旋转按钮的右边和底部建立旋转view,并给他增加旋转手势
//旋转view
[self.rotationView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(self.zoomButton).mas_offset(-2*buttonWidthAndHeight);
make.right.mas_equalTo(self.zoomButton);
make.top.mas_equalTo(self.zoomButton).mas_offset(-2*buttonWidthAndHeight);
make.bottom.mas_equalTo(self.zoomButton);
}];
KTOneFingerRotationGestureRecognizer *rotation = [[KTOneFingerRotationGestureRecognizer alloc] initWithTarget:self action: @selector(rotating:)];
[self addGestureRecognizer:rotation];
(3)旋转动作实现:
判断接触点是否在旋转view上,如果在则进行旋转
//旋转实现
- (void)rotating:(KTOneFingerRotationGestureRecognizer *)recognizer
{
//获得触碰点在view上的位置
CGPoint point = [recognizer locationInView:self];
// point = [self.rotationView.layer convertPoint:point fromLayer:self.layer];
NSLog(@"进行旋转:point=%f,%f",point.x,point.y);
//判断点是否在旋转视图上
BOOL result = [self.rotationView.layer containsPoint:point];//self.layer->self.rotationView.layer?
if (!result) {
NSLog(@"Not in button");
return;
}
//如果在进行旋转
[self setTransform:CGAffineTransformRotate([self transform], [recognizer rotation])];
NSLog(@" [recognizer rotation]=%f", [recognizer rotation]);
if (self.rotationBlock) {
self.rotationBlock([recognizer rotation]);//这里设置字体随框旋转,需要api接口,就不放上来了
}
}