Item里面的代码处理:
__block bool move = false;
__block CGPoint beginPoint = CGPointZero;
[self.scanImageView kj_AddGestureRecognizer:(KJGestureTypePan) block:^(UIView * _Nonnull view, UIGestureRecognizer * _Nonnull gesture) {
CGPoint point = [gesture locationInView:view];
if (gesture.state == UIGestureRecognizerStateBegan) {
beginPoint = [gesture locationInView:view];
}else if (point.y <= 5 && move == false) {
move = true;
CGPoint pt = [gesture locationInView:kKeyWindow];
if (weakself.kMoveBlock) weakself.kMoveBlock(weakself,pt,0);
}else if (move && point.y < 5 && gesture.state == UIGestureRecognizerStateChanged) {
CGPoint pt = [gesture locationInView:kKeyWindow];
if (weakself.kMoveBlock) weakself.kMoveBlock(weakself,pt,1);
}else if (gesture.state == UIGestureRecognizerStateRecognized) {
move = false;
beginPoint = CGPointZero;
CGPoint pt = [gesture locationInView:kKeyWindow];
if (weakself.kMoveBlock) weakself.kMoveBlock(weakself,pt,2);
}else {
point.x = beginPoint.x - point.x;
point.y = beginPoint.y - point.y;
if (weakself.kMoveTableBlock) weakself.kMoveTableBlock(weakself,point);
}
}];
CollectionView处的代码处理:
/// 拖动手势回调
cell.kMoveBlock = ^(UICollectionViewCell *item,CGPoint point,NSInteger move){
if (weakSelf.matterImageMoveBlock) {
NSIndexPath *idx = kIndexpathSubviewCollectionview(item, self.collectView);
weakSelf.matterImageMoveBlock(move,point,idx.row-1);
}
};
cell.kMoveTableBlock = ^(UICollectionViewCell *item,CGPoint point) {
NSLog(@"---:%.2f,%.2f",weakSelf.collectView.contentOffset.x,point.x);
if (abs(point.x) < 5) {
return;
}
weakSelf.collectView.contentOffset = CGPointMake(point.x,0);
};
contentOffset
排除点不完美的情况,会导致左右拖动的时候出现CollectionView跳动的情况扩展代码H文件:
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, KJMoveStateType) {
KJMoveStateTypeBegin = 0,
KJMoveStateTypeMove,
KJMoveStateTypeEnd,
KJMoveStateTypeCancelled,
};
typedef void(^KJMoveBlock)(KJMoveStateType state,CGPoint point);
@interface UICollectionView (KJTouch)
/// 开启方法交换
@property(nonatomic,assign)bool kOpenExchange;
/// Touch里面移动回调,需要开启方法交换才处理
@property(nonatomic,readwrite,copy)KJMoveBlock moveblock;
@end
NS_ASSUME_NONNULL_END
扩展代码M文件:
@implementation NSObject (Swizzling)
+ (BOOL)kj_swizzleMethod:(SEL)origSel Method:(SEL)altSel {
Method origMethod = class_getInstanceMethod(self, origSel);
Method altMethod = class_getInstanceMethod(self, altSel);
if (!origMethod || !altMethod) return NO;
class_addMethod(self, origSel, class_getMethodImplementation(self, origSel), method_getTypeEncoding(origMethod));
class_addMethod(self, altSel, class_getMethodImplementation(self, altSel), method_getTypeEncoding(altMethod));
method_exchangeImplementations(class_getInstanceMethod(self, origSel), class_getInstanceMethod(self, altSel));
return YES;
}
@end
@implementation UICollectionView (Touch)
- (bool)kOpenExchange{
return [objc_getAssociatedObject(self,@selector(kOpenExchange)) boolValue];
}
- (void)setKOpenExchange:(bool)kOpenExchange{
objc_setAssociatedObject(self,@selector(kOpenExchange),[NSNumber numberWithBool:kOpenExchange],OBJC_ASSOCIATION_ASSIGN);
}
- (KJMoveBlock)moveblock{
return (KJMoveBlock)objc_getAssociatedObject(self, @selector(moveblock));
}
- (void)setMoveblock:(KJMoveBlock)moveblock{
objc_setAssociatedObject(self, @selector(moveblock), moveblock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self kj_swizzleMethod:@selector(touchesBegan:withEvent:) Method:@selector(kj_touchesBegan:withEvent:)];
[self kj_swizzleMethod:@selector(touchesMoved:withEvent:) Method:@selector(kj_touchesMoved:withEvent:)];
[self kj_swizzleMethod:@selector(touchesEnded:withEvent:) Method:@selector(kj_touchesEnded:withEvent:)];
[self kj_swizzleMethod:@selector(touchesCancelled:withEvent:) Method:@selector(kj_touchesCancelled:withEvent:)];
});
}
- (void)kj_touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
if (self.kOpenExchange && self.moveblock) {
CGPoint point = [[touches anyObject] locationInView:self];
self.moveblock(KJMoveStateTypeBegin,point);
}
[self kj_touchesBegan:touches withEvent:event];
}
- (void)kj_touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event{
if (self.kOpenExchange && self.moveblock) {
CGPoint point = [[touches anyObject] locationInView:self];
self.moveblock(KJMoveStateTypeMove,point);
}
[self kj_touchesMoved:touches withEvent:event];
}
- (void)kj_touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event{
if (self.kOpenExchange && self.moveblock) {
CGPoint point = [[touches anyObject] locationInView:self];
self.moveblock(KJMoveStateTypeEnd,point);
}
[self kj_touchesEnded:touches withEvent:event];
}
- (void)kj_touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event{
if (self.kOpenExchange && self.moveblock) {
CGPoint point = [[touches anyObject] locationInView:self];
self.moveblock(KJMoveStateTypeCancelled,point);
}
[self kj_touchesEnded:touches withEvent:event];
}
@end
使用方式:
@interface KJCollectionVC ()
@property(nonatomic,strong)UICollectionView *collectView;
@property(nonatomic,strong)UIImageView *imageView;
@end
@implementation KJCollectionVC
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.view addSubview:self.collectView];
[self.view addSubview:self.imageView];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section{
return 10;
}
- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"item" forIndexPath:indexPath];
cell.backgroundColor = [kRandomColor() colorWithAlphaComponent:0.9];
return cell;
}
#pragma mark - UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(60, 60);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(10, 10, 10, 10);
}
- (UIImageView*)imageView{
if (!_imageView) {
_imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 60, 60)];
_imageView.contentMode = UIViewContentModeScaleAspectFit;
_imageView.hidden = YES;
_imageView.layer.borderWidth = 2.;
_imageView.layer.borderColor = UIColor.redColor.CGColor;
_imageView.image = kGetImage(@"timg-2");
}
return _imageView;
}
- (UICollectionView*)collectView{
if (_collectView == nil) {
UICollectionViewFlowLayout *layOut = [[UICollectionViewFlowLayout alloc] init];
[layOut setScrollDirection:UICollectionViewScrollDirectionHorizontal];
layOut.minimumLineSpacing = 10;
layOut.minimumInteritemSpacing = 10;
_collectView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, kScreenH-70, kScreenW, 70) collectionViewLayout:layOut];
_collectView.delegate = self;
_collectView.dataSource = self;
_collectView.alwaysBounceHorizontal = YES;
_collectView.showsHorizontalScrollIndicator = NO;
_collectView.bounces = YES;
_collectView.backgroundColor = [UIColor.greenColor colorWithAlphaComponent:0.3];
[_collectView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"item"];
_collectView.kOpenExchange = true;
_weakself;
__block bool move = false;
_collectView.moveblock = ^(KJMoveStateType state, CGPoint point) {
if (point.y <= 30 && move == false) {
move = true;
point = [weakself.collectView convertPoint:point toView:kKeyWindow];
NSIndexPath *idx = [weakself.collectView indexPathForItemAtPoint:point];
UICollectionViewCell *nextCell = [weakself.collectView cellForItemAtIndexPath:idx];
weakself.imageView.backgroundColor = nextCell.backgroundColor;
weakself.imageView.center = point;
weakself.imageView.hidden = NO;
}else if (move && point.y < 30 && state == KJMoveStateTypeMove) {
point = [weakself.collectView convertPoint:point toView:kKeyWindow];
weakself.imageView.center = point;
weakself.collectView.scrollEnabled = NO;
return;
}else if (state == KJMoveStateTypeEnd || state == KJMoveStateTypeCancelled) {
move = false;
point = [weakself.collectView convertPoint:point toView:kKeyWindow];
weakself.imageView.center = CGPointZero;
weakself.imageView.hidden = YES;
}
weakself.collectView.scrollEnabled = YES;
};
}
return _collectView;
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
pod 'KJExtensionHandler'
引入即可