看完上一篇的手势识别器之后,写了一个关于手势拖动Item进行移动变换顺序的demo
主要用的长按手势,效果如下:
demo地址:http://download.csdn.net/detail/tuwanli125/9470311
demo下载地址:https://github.com/tuwanli/ItemOrder
大概解说一下代码,
ViewController.m
<span style="font-size:18px;">#define k_width [UIScreen mainScreen].bounds.size.width
#define k_height [UIScreen mainScreen].bounds.size.height
#define AirButtonHeight ([UIScreen mainScreen].bounds.size.width/4+5)
#import "ViewController.h"
#import "HomeHeadView.h"
@interface ViewController ()
@property (nonatomic,strong)NSMutableArray *MenuArr;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self initUI];
}
- (void)initUI
{
_MenuArr = [[NSMutableArray alloc]init];
for (int i=0; i<8; i++) {
NSString *str1 = [NSString stringWithFormat:@"title%d",i];
NSString *str2 = [NSString stringWithFormat:@"%d",i+1];
NSDictionary *dict = @{@"name":str2,@"title":str1};
[_MenuArr addObject:dict];
}
NSLog(@"%@",_MenuArr);
HomeHeadView *homeView = [[HomeHeadView alloc]initWithFrame:CGRectMake(0, 64, k_width, 91+(AirButtonHeight*2)+5)];
[homeView configWithModelArr:_MenuArr];
[self.view addSubview:homeView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
</span>
创建HomeHeadView类
HomeHeadView.h
<span style="font-size:18px;">#import <UIKit/UIKit.h>
#import "AreaButton.h"
@interface HomeHeadView : UIView
{
// 开始拖动的view的下一个view的CGPoint(如果开始位置是0 结束位置是4 nextPoint值逐个往下算)
CGPoint nextPoint;
// 用于赋值CGPoint
CGPoint valuePoint;
UIView *backView;
}
@property (nonatomic,strong)NSMutableArray *modelArr;
-(void)configWithModelArr:(NSArray *)dataArr;
@end</span>
HomeHeadView.m
<span style="font-size:18px;">#define KBase_tag 100
#define k_width [UIScreen mainScreen].bounds.size.width
#define k_height [UIScreen mainScreen].bounds.size.height
#define AirButtonHeight ([UIScreen mainScreen].bounds.size.width/4+5)
#import "HomeHeadView.h"
//#import "Tool.h"
@implementation HomeHeadView
-(void)configWithModelArr:(NSArray *)dataArr
{
backView = [[UIView alloc]initWithFrame:CGRectMake(0, 91, k_width, AirButtonHeight*2)];
backView.backgroundColor = [UIColor whiteColor];
[self addSubview:backView];
self.modelArr = [NSMutableArray arrayWithArray:dataArr];
//创建按钮
// CGFloat buttonWidth = self.frame.size.width/4;
for (int i = 0 ; i < dataArr.count; i++) {
AreaButton *area = [[AreaButton alloc]initWithFrame:CGRectMake(i%4*AirButtonHeight, i/4*AirButtonHeight, AirButtonHeight, AirButtonHeight) Model:self.modelArr[i]];
area.tag = KBase_tag+i;
[backView addSubview:area];
// 长按手势
UILongPressGestureRecognizer * longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[area addGestureRecognizer:longPress];
}
}
/**
* 长按手势
*/
-(void)longPress:(UIGestureRecognizer*)recognizer{
//
AreaButton *recognizerView = (AreaButton *)recognizer.view;
// 禁用其他按钮的拖拽手势
for (UIButton * bt in backView.subviews) {
if (bt!=recognizerView) {
bt.userInteractionEnabled = NO;
}
}
// 长按视图在父视图中的位置(触摸点的位置)
CGPoint recognizerPoint = [recognizer locationInView:backView];
NSLog(@"_____%@",NSStringFromCGPoint(recognizerPoint));
if (recognizer.state == UIGestureRecognizerStateBegan) {
// 开始的时候改变拖动view的外观(放大,改变颜色等)
[UIView animateWithDuration:0.2 animations:^{
recognizerView.transform = CGAffineTransformMakeScale(1.3, 1.3);
recognizerView.alpha = 0.7;
}];
// 把拖动view放到最上层
[backView bringSubviewToFront:recognizerView];
// valuePoint保存最新的移动位置
valuePoint = recognizerView.center;
recognizerView.moveImg.hidden = NO;
}else if(recognizer.state == UIGestureRecognizerStateChanged){
// 更新pan.view的center
recognizerView.center = recognizerPoint;
/**
* 可以创建一个继承UIButton的类(MyButton),这样便于扩展,增加一些属性来绑定数据
* 如果在self.view上加其他控件拖拽会奔溃,可以在下面方法里面加判断MyButton,也可以把所有按钮放到一个全局变量的UIView上来替换self.view
*/
for (UIButton * bt in backView.subviews) {
// 判断是否移动到另一个view区域
// CGRectContainsPoint(rect,point) 判断某个点是否被某个frame包含
if (CGRectContainsPoint(bt.frame, recognizerView.center)&&bt!=recognizerView)
{
NSLog(@"bt_______%@",bt);
// 开始位置
NSInteger fromIndex = recognizerView.tag - KBase_tag;
// 需要移动到的位置
NSInteger toIndex = bt.tag - KBase_tag;
NSLog(@"开始位置=%ld 结束位置=%ld",fromIndex,toIndex);
// 往后移动
if ((toIndex-fromIndex)>0) {
// 从开始位置移动到结束位置
// 把移动view的下一个view移动到记录的view的位置(valuePoint),并把下一view的位置记为新的nextPoint,并把view的tag值-1,依次类推
[UIView animateWithDuration:0.2 animations:^{
for (NSInteger i = fromIndex+1; i<=toIndex; i++) {
UIButton * nextBt = (UIButton*)[backView viewWithTag:KBase_tag+i];
nextPoint = nextBt.center;
nextBt.center = valuePoint;
valuePoint = nextPoint;
nextBt.tag--;
}
recognizerView.tag = KBase_tag + toIndex;
}];
}
// 往前移动
else
{
// 从开始位置移动到结束位置
// 把移动view的上一个view移动到记录的view的位置(valuePoint),并把上一view的位置记为新的nextPoint,并把view的tag值+1,依次类推
[UIView animateWithDuration:0.2 animations:^{
for (NSInteger i = fromIndex-1; i>=toIndex; i--) {
UIButton * nextBt = (UIButton*)[backView viewWithTag:KBase_tag+i];
nextPoint = nextBt.center;
nextBt.center = valuePoint;
valuePoint = nextPoint;
nextBt.tag++;
}
recognizerView.tag = KBase_tag + toIndex;
}];
}
}
}
}else if(recognizer.state == UIGestureRecognizerStateEnded){
// 恢复其他按钮的拖拽手势
for (UIButton * bt in backView.subviews) {
if (bt!=recognizerView) {
bt.userInteractionEnabled = YES;
}
}
// 结束时候恢复view的外观(放大,改变颜色等)
[UIView animateWithDuration:0.2 animations:^{
recognizerView.transform = CGAffineTransformMakeScale(1.0, 1.0);
recognizerView.alpha = 1;
recognizerView.center = valuePoint;
}];
recognizerView.moveImg.hidden = YES;
//记录button
}
}
@end</span>
创建按钮的类AreaButton
AreaButton.h
<span style="font-size:18px;">#import <UIKit/UIKit.h>
@interface AreaButton : UIButton
@property (nonatomic,retain) UIImageView *moveImg;
-(AreaButton *)initWithFrame:(CGRect)frame Model:(NSDictionary *)model;
@end</span>
AreaButton.m
<span style="font-size:18px;">#import "AreaButton.h"
@implementation AreaButton
-(AreaButton *)initWithFrame:(CGRect)frame Model:(NSDictionary *)model
{
self = [AreaButton buttonWithType:UIButtonTypeCustom];
self.frame = frame;
CGFloat imageWidth = 30;
//
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake((frame.size.width-imageWidth)/2, (frame.size.width-imageWidth)/2-10, imageWidth, imageWidth)];
[imageView setImage:[UIImage imageNamed:model[@"name"]]];
[self addSubview:imageView];
//title
UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(0,imageView.frame.size.height+imageView.frame.origin.y+5,frame.size.width , 20)];
[titleLabel setText:model[@"title"]];
[titleLabel setFont:[UIFont systemFontOfSize:14]];
titleLabel.textAlignment = NSTextAlignmentCenter;
[titleLabel setTextColor:[UIColor grayColor]];
[self addSubview:titleLabel];
self.layer.borderWidth = 0.5;
self.layer.borderColor = [UIColor colorWithRed:200/255.0 green:200/255.0 blue:200/255.0 alpha:1].CGColor;
self.backgroundColor = [UIColor whiteColor];
self.moveImg = [[UIImageView alloc]initWithFrame:CGRectMake(frame.size.width-25,5, 20, 20)];
[self.moveImg setImage:[UIImage imageNamed:@"ButtonMove.png"]];
self.moveImg.hidden = YES;
[self addSubview:self.moveImg];
return self;
}
@end
</span>