iOS拖動按鈕排序UI效果

來源:互聯網
上載者:User

    項目中遇到過拖動按鈕排序的效果需求,網上的也只是寫零散的講解,簡單的研究過後做了個Demo並封裝了自訂控制項供大家一起學習.廢話不多講,先上效果圖再說:

 PS:也請大家支援IM_Loser 還有我的GitHub :IMLoser如有不足 大家一起討論~

Demo地址 : https://github.com/IMLoser/HWSortViewDemo 記的點個星星支援下喲~


總結起來,其實想要實現這個效果有這麼幾個解決的步驟:

1. 九宮格的排序

2. 點擊按鈕拖動(包含添加手勢,監聽手勢的狀態變化...)

3. 長按按鈕觸發可拖動狀態(我這裡用的是長按按鈕變大和變透明...)

4. 記錄按鈕初始位置,拖動後可自動複位(就是用屬性記錄拖動前按鈕中心點的位置...)

5. 在手勢方法中判斷拖動時是否進入其他按鈕範圍(如果重疊,開始根據tag排序按鈕位置,從而實現對應的UI效果...)


下面展示核心代碼吧

#import "HWSortView.h"#define SELF_SIZE self.frame.size#define DEFAULT_COLUMN_MARGIN 10#define DEFAULT_COLUMN_COUNT 3#define RGB_COLOR [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:0.8]@interface HWSortView ()@property (strong, nonatomic) NSMutableArray * buttons;@property (assign, nonatomic) CGPoint startP;@property (assign, nonatomic) CGPoint buttonP;@end@implementation HWSortView- (NSMutableArray *)buttons {        if (!_buttons) {        _buttons = [NSMutableArray array];    }    return _buttons;}+ (instancetype)sortView{    HWSortView * sortView = [[HWSortView alloc] init];    sortView.backgroundColor = [UIColor clearColor];    return sortView;}+ (instancetype)sortViewWithTitlesArray:(NSMutableArray *)titlesArray{    HWSortView * sortView = [HWSortView sortView];    sortView.titlesArray = titlesArray;    [sortView initailButtons];    return sortView;}- (void)initailButtons{    if (!_titlesArray.count) return;    for (NSInteger i = 0; i < _titlesArray.count; i++) {        UIButton * movedBtn = [UIButton buttonWithType:(UIButtonTypeSystem)];        [movedBtn setBackgroundColor:RGB_COLOR];        movedBtn.layer.cornerRadius = 5;        [movedBtn setTitleColor:[UIColor whiteColor] forState:(UIControlStateNormal)];        [movedBtn setTitle:_titlesArray[i] forState:(UIControlStateNormal)];        [self.buttons addObject:movedBtn];        movedBtn.tag = i;        [self addSubview:movedBtn];                // 添加長按手勢        UILongPressGestureRecognizer * longGes = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressClick:)];        [movedBtn addGestureRecognizer:longGes];    }}- (void)layoutSubviews{    [super layoutSubviews];       static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        [self settingButtonFrame];    });}// 布局九宮格- (void)settingButtonFrame{    if (0 == _columnMargin) { _columnMargin = DEFAULT_COLUMN_MARGIN; }    if (0 == _columnCount) { _columnCount = DEFAULT_COLUMN_COUNT; }        CGFloat buttonH = 30;    CGFloat buttonW = (SELF_SIZE.width - _columnMargin * (_columnCount + 1)) / _columnCount * 1.0;    CGFloat buttonX = 0;    CGFloat buttonY = 0;    // 設定按鈕初始位置    for (NSInteger i = 0; i < self.buttons.count; i++) {        NSInteger column = i % _columnCount;        NSInteger row = i / _columnCount;        buttonX = _columnMargin + column * (buttonW + _columnMargin);        buttonY = _columnMargin + row * (buttonH + _columnMargin);        UIButton * btn = self.buttons[i];        btn.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);    }}// 設定按鈕文字顏色- (void)setTitlesColor:(UIColor *)titlesColor {        _titlesColor = titlesColor;    for (UIButton * movedBtn in _buttons) {        [movedBtn setTitleColor:_titlesColor forState:(UIControlStateNormal)];    }    }#pragma MARK - < Button_Gesture >- (void)longPressClick:(UIGestureRecognizer *)longGes{    UIButton * currentBtn = (UIButton *)longGes.view;        if (UIGestureRecognizerStateBegan == longGes.state) {        [UIView animateWithDuration:0.2 animations:^{            currentBtn.transform = CGAffineTransformScale(currentBtn.transform, 1.2, 1.2);            currentBtn.alpha = 0.7f;            _startP = [longGes locationInView:currentBtn];            _buttonP = currentBtn.center;        }];    }        if (UIGestureRecognizerStateChanged == longGes.state) {        CGPoint newP = [longGes locationInView:currentBtn];        CGFloat movedX = newP.x - _startP.x;        CGFloat movedY = newP.y - _startP.y;        currentBtn.center = CGPointMake(currentBtn.center.x + movedX, currentBtn.center.y + movedY);                // 擷取當前按鈕的索引        NSInteger fromIndex = currentBtn.tag;        // 擷取目標移動索引        NSInteger toIndex = [self getMovedIndexByCurrentButton:currentBtn];                if (toIndex < 0) {            return;        } else {                        currentBtn.tag = toIndex;            // 按鈕向後移動            if (fromIndex < toIndex) {                                for (NSInteger i = fromIndex; i < toIndex; i++) {                    // 拿到下一個按鈕                    UIButton * nextBtn = self.buttons[i + 1];                    CGPoint tempP = nextBtn.center;                    [UIView animateWithDuration:0.5 animations:^{                        nextBtn.center = _buttonP;                    }];                    _buttonP = tempP;                    nextBtn.tag = i;                }                [self sortArray];            } else if(fromIndex > toIndex) { // 按鈕向前移動                                for (NSInteger i = fromIndex; i > toIndex; i--) {                    UIButton * previousBtn = self.buttons[i - 1];                    CGPoint tempP = previousBtn.center;                    [UIView animateWithDuration:0.5 animations:^{                        previousBtn.center = _buttonP;                    }];                    _buttonP = tempP;                    previousBtn.tag = i;                }                [self sortArray];            }        }    }        // 手指鬆開之後 進行的處理    if (UIGestureRecognizerStateEnded == longGes.state) {        [UIView animateWithDuration:0.2 animations:^{            currentBtn.transform = CGAffineTransformIdentity;            currentBtn.alpha = 1.0f;            currentBtn.center = _buttonP;        }];    }}- (void)sortArray{    // 對已改變按鈕的數組進行排序    [_buttons sortUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {        UIButton *temp1 = (UIButton *)obj1;        UIButton *temp2 = (UIButton *)obj2;        return temp1.tag > temp2.tag;    //將tag值大的按鈕向後移    }];    }// 擷取按鈕移動目標索引- (NSInteger)getMovedIndexByCurrentButton:(UIButton *)currentButton{    for (NSInteger i = 0; i<self.buttons.count ; i++) {        UIButton * button = self.buttons[i];        if (!currentButton || button != currentButton) {            if (CGRectContainsPoint(button.frame, currentButton.center)) {                return i;            }        }    }    return -1;}@end


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.