看完上一篇的手勢識別器之後,寫了一個關於手勢拖動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>