ifish/Ifish/views/Photo/ZYDraggableView/UIView+ZYDraggable.m

143 lines
4.6 KiB
Objective-C
Executable File

//
// UIView+ZYDraggable.m
// DraggableView
//
// Created by 张志延 on 16/8/25. (https://github.com/zzyspace)
// Copyright © 2016年 tongbu. All rights reserved.
//
#import "UIView+ZYDraggable.h"
#import <objc/runtime.h>
@implementation UIView (Draggable)
- (void)makeDraggable
{
NSAssert(self.superview, @"Super view is required when make view draggable");
[self makeDraggableInView:self.superview damping:0.4];
}
- (void)makeDraggableInView:(UIView *)view damping:(CGFloat)damping
{
if (!view) return;
[self removeDraggable];
self.zy_playground = view;
self.zy_damping = damping;
[self zy_creatAnimator];
[self zy_addPanGesture];
}
- (void)removeDraggable
{
[self removeGestureRecognizer:self.zy_panGesture];
self.zy_panGesture = nil;
self.zy_playground = nil;
self.zy_animator = nil;
self.zy_snapBehavior = nil;
self.zy_attachmentBehavior = nil;
self.zy_centerPoint = CGPointZero;
}
- (void)updateSnapPoint
{
self.zy_centerPoint = [self convertPoint:CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2) toView:self.zy_playground];
self.zy_snapBehavior = [[UISnapBehavior alloc] initWithItem:self snapToPoint:self.zy_centerPoint];
self.zy_snapBehavior.damping = self.zy_damping;
}
- (void)zy_creatAnimator
{
self.zy_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.zy_playground];
[self updateSnapPoint];
}
- (void)zy_addPanGesture
{
self.zy_panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(zy_panGesture:)];
[self addGestureRecognizer:self.zy_panGesture];
}
#pragma mark - Gesture
- (void)zy_panGesture:(UIPanGestureRecognizer *)pan
{
CGPoint panLocation = [pan locationInView:self.zy_playground];
if (pan.state == UIGestureRecognizerStateBegan)
{
UIOffset offset = UIOffsetMake(panLocation.x - self.zy_centerPoint.x, panLocation.y - self.zy_centerPoint.y);
[self.zy_animator removeAllBehaviors];
self.zy_attachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self
offsetFromCenter:offset
attachedToAnchor:panLocation];
[self.zy_animator addBehavior:self.zy_attachmentBehavior];
}
else if (pan.state == UIGestureRecognizerStateChanged)
{
[self.zy_attachmentBehavior setAnchorPoint:panLocation];
}
else if (pan.state == UIGestureRecognizerStateEnded ||
pan.state == UIGestureRecognizerStateCancelled ||
pan.state == UIGestureRecognizerStateFailed)
{
[self.zy_animator removeAllBehaviors];
[self.zy_animator addBehavior:self.zy_snapBehavior];
}
}
#pragma mark - Associated Object
- (void)setZy_playground:(id)object {
objc_setAssociatedObject(self, @selector(zy_playground), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIView *)zy_playground {
return objc_getAssociatedObject(self, @selector(zy_playground));
}
- (void)setZy_animator:(id)object {
objc_setAssociatedObject(self, @selector(zy_animator), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIDynamicAnimator *)zy_animator {
return objc_getAssociatedObject(self, @selector(zy_animator));
}
- (void)setZy_snapBehavior:(id)object {
objc_setAssociatedObject(self, @selector(zy_snapBehavior), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UISnapBehavior *)zy_snapBehavior {
return objc_getAssociatedObject(self, @selector(zy_snapBehavior));
}
- (void)setZy_attachmentBehavior:(id)object {
objc_setAssociatedObject(self, @selector(zy_attachmentBehavior), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIAttachmentBehavior *)zy_attachmentBehavior {
return objc_getAssociatedObject(self, @selector(zy_attachmentBehavior));
}
- (void)setZy_panGesture:(id)object {
objc_setAssociatedObject(self, @selector(zy_panGesture), object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIPanGestureRecognizer *)zy_panGesture {
return objc_getAssociatedObject(self, @selector(zy_panGesture));
}
- (void)setZy_centerPoint:(CGPoint)point {
objc_setAssociatedObject(self, @selector(zy_centerPoint), [NSValue valueWithCGPoint:point], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGPoint)zy_centerPoint {
return [objc_getAssociatedObject(self, @selector(zy_centerPoint)) CGPointValue];
}
- (void)setZy_damping:(CGFloat)damping {
objc_setAssociatedObject(self, @selector(zy_damping), @(damping), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (CGFloat)zy_damping {
return [objc_getAssociatedObject(self, @selector(zy_damping)) floatValue];
}
@end