前言
· UIView是我們在開發(fā)中經(jīng)常使用到的控件层皱,很多時(shí)候需要在該控件上面添加手勢處理龄糊。常規(guī)的做法就是實(shí)例手勢然后添加奴曙,程序員都是很懶的,并且我也一直比較喜歡東西都放在一起查找起來也方便邓厕。常規(guī)的聲明和處理分開在代碼量巨大的情形之下找起來還是略顯麻煩逝嚎,所以我將手勢封裝一下,方便使用
. Demo地址
API
NS_ASSUME_NONNULL_BEGIN
typedef void(^KJGestureRecognizerBlock)(UIView *view, UIGestureRecognizer *gesture);
typedef NS_ENUM(NSUInteger, KJGestureType) {
KJGestureTypeTap, // 點(diǎn)擊
KJGestureTypeDouble, // 雙擊
KJGestureTypeLongPress, // 長按
KJGestureTypeSwipe, // 輕掃
KJGestureTypePan, // 移動(dòng)
KJGestureTypeRotate, // 旋轉(zhuǎn)
KJGestureTypePinch, // 縮放
};
static NSString * const _Nonnull KJGestureTypeStringMap[] = {
[KJGestureTypeTap] = @"UITapGestureRecognizer",
[KJGestureTypeDouble] = @"UITapGestureRecognizer",
[KJGestureTypeLongPress] = @"UILongPressGestureRecognizer",
[KJGestureTypeSwipe] = @"UISwipeGestureRecognizer",
[KJGestureTypePan] = @"UIPanGestureRecognizer",
[KJGestureTypeRotate] = @"UIRotationGestureRecognizer",
[KJGestureTypePinch] = @"UIPinchGestureRecognizer",
};
@interface UIView (KJGestureBlock)
/// 單擊手勢
- (UIGestureRecognizer*)kj_AddTapGestureRecognizerBlock:(KJGestureRecognizerBlock)block;
/// 手勢處理
- (UIGestureRecognizer*)kj_AddGestureRecognizer:(KJGestureType)type block:(KJGestureRecognizerBlock)block;
@end
NS_ASSUME_NONNULL_END
使用示例
_weakself;
[self.displayImageView kj_AddTapGestureRecognizerBlock:^(UIView * _Nonnull view, UIGestureRecognizer * _Nonnull gesture) {
NSLog(@"單擊");
}];
[self.displayImageView kj_AddGestureRecognizer:(KJGestureTypeDouble) block:^(UIView * _Nonnull view, UIGestureRecognizer * _Nonnull gesture) {
NSLog(@"雙擊");
}];
[self.displayImageView kj_AddGestureRecognizer:(KJGestureTypePan) block:^(UIView * _Nonnull view, UIGestureRecognizer * _Nonnull gesture) {
UIPanGestureRecognizer *panGestureRecognizer = (UIPanGestureRecognizer*)gesture;
CGPoint translation = [panGestureRecognizer translationInView:panGestureRecognizer.view];
NSLog(@"移動(dòng)%.2f",translation.x);
}];
[self.displayImageView kj_AddGestureRecognizer:(KJGestureTypePinch) block:^(UIView * _Nonnull view, UIGestureRecognizer * _Nonnull gesture) {
UIPinchGestureRecognizer *pinchGestureRecognizer = (UIPinchGestureRecognizer*)gesture;
NSLog(@"縮放%.2f,%.2f",weakself.lastScale,pinchGestureRecognizer.scale);
switch (pinchGestureRecognizer.state) {
case UIGestureRecognizerStateBegan:
case UIGestureRecognizerStateChanged:{
CGFloat scale = weakself.lastScale+pinchGestureRecognizer.scale-1;
if (scale >= weakself.maxScale || scale <= weakself.minScale) {
return;
}
CGFloat w = kScreenW * scale;
CGFloat h = kScreenH * scale;
CGFloat x = weakself.originRect.origin.x - (kScreenW*(scale-1))/2.;
CGFloat y = weakself.originRect.origin.y - (kScreenH*(scale-1))/2.;
view.frame = CGRectMake(x, y, w, h);
}
break;
case UIGestureRecognizerStateEnded:{
CGFloat scale = weakself.lastScale+pinchGestureRecognizer.scale-1;
if (scale >= weakself.maxScale) {
weakself.lastScale = weakself.maxScale;
}else if (scale <= weakself.minScale) {
weakself.lastScale = weakself.minScale;
}else{
weakself.lastScale += (pinchGestureRecognizer.scale-1);
}
}
break;
default:
break;
}
}];
簡單介紹
1. 開啟視圖的交互
外界使用的時(shí)候也不需要再寫該屬性详恼,又省一句代碼- -|
self.userInteractionEnabled = YES;
2. 聲明和添加
這里提供七種手勢枚舉
typedef NS_ENUM(NSUInteger, KJGestureType) {
KJGestureTypeTap, // 點(diǎn)擊
KJGestureTypeDouble, // 雙擊
KJGestureTypeLongPress, // 長按
KJGestureTypeSwipe, // 輕掃
KJGestureTypePan, // 移動(dòng)
KJGestureTypeRotate, // 旋轉(zhuǎn)
KJGestureTypePinch, // 縮放
};
static NSString * const _Nonnull KJGestureTypeStringMap[] = {
[KJGestureTypeTap] = @"UITapGestureRecognizer",
[KJGestureTypeDouble] = @"UITapGestureRecognizer",
[KJGestureTypeLongPress] = @"UILongPressGestureRecognizer",
[KJGestureTypeSwipe] = @"UISwipeGestureRecognizer",
[KJGestureTypePan] = @"UIPanGestureRecognizer",
[KJGestureTypeRotate] = @"UIRotationGestureRecognizer",
[KJGestureTypePinch] = @"UIPinchGestureRecognizer",
};
NSClassFromString得到對應(yīng)的手勢類
NSString *string = KJGestureTypeStringMap[type];
__block UIGestureRecognizer *gesture = [[NSClassFromString(string) alloc] initWithTarget:self action:@selector(kGestureAction:)];
[gesture setDelaysTouchesBegan:YES];
[self addGestureRecognizer:gesture];
3. 解決單擊和雙擊共存問題
if (type == KJGestureTypeTap) {
[self.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer *recognizer, NSUInteger idx, BOOL *stop) {
if ([recognizer isKindOfClass:[UITapGestureRecognizer class]] && ((UITapGestureRecognizer*)recognizer).numberOfTapsRequired == 2) {
[gesture requireGestureRecognizerToFail:recognizer];
*stop = YES;
}
}];
string = [string stringByAppendingString:@"Tap"];
}else if (type == KJGestureTypeDouble) {
[(UITapGestureRecognizer*)gesture setNumberOfTapsRequired:2];
[self.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer *recognizer, NSUInteger idx, BOOL *stop) {
if ([recognizer isKindOfClass:[UITapGestureRecognizer class]] && ((UITapGestureRecognizer*)recognizer).numberOfTapsRequired == 1) {
[recognizer requireGestureRecognizerToFail:gesture];
*stop = YES;
}
}];
string = [string stringByAppendingString:@"Double"];
}
4. 保存回調(diào)
這里增加一個(gè)selectorString
屬性來區(qū)分不同的回調(diào)
self.selectorString = string;
self.gesrureblock = block;
NSSelectorFromString 得到不同的回調(diào)
#pragma mark - associated
- (NSString*)selectorString{
return objc_getAssociatedObject(self, @selector(selectorString));
}
- (void)setSelectorString:(NSString*)selectorString{
objc_setAssociatedObject(self, @selector(selectorString), selectorString, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (KJGestureRecognizerBlock)gesrureblock{
return (KJGestureRecognizerBlock)objc_getAssociatedObject(self, NSSelectorFromString(self.selectorString));
}
- (void)setGesrureblock:(KJGestureRecognizerBlock)gesrureblock{
objc_setAssociatedObject(self, NSSelectorFromString(self.selectorString), gesrureblock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
5. 處理手勢
- (void)kGestureAction:(UIGestureRecognizer*)gesture{
NSString *string = NSStringFromClass([gesture class]);
if ([gesture isKindOfClass:[UITapGestureRecognizer class]]) {
if (((UITapGestureRecognizer*)gesture).numberOfTapsRequired == 1) {
string = [string stringByAppendingString:@"Tap"];
}else {
string = [string stringByAppendingString:@"Double"];
}
}
self.selectorString = string;
self.gesrureblock(gesture.view, gesture);
}