iOS開發(fā) UICollectionView無限拖拽排序功能實(shí)現(xiàn)

現(xiàn)在很多app功能點(diǎn)都非常多雌团,如果將功能點(diǎn)都放在首頁,這樣就感覺比較亂聘惦,而且功能的主次也不容易區(qū)分某饰,用戶有些功能點(diǎn)是不需要經(jīng)常操作的儒恋,像支付寶的功能點(diǎn)就非常多,因此支持用戶自定義排序就非常有必要黔漂,筆者現(xiàn)在的項(xiàng)目功能點(diǎn)也非常之多诫尽,因此也支持用戶自定義排序,用戶可以自己選擇在首頁展示多少個(gè)功能炬守,功能的順序牧嫉,用戶也可以自己設(shè)置。這是項(xiàng)目的效果圖:

屏幕快照 2017-09-23 09.46.13.png
屏幕快照 2017-09-23 09.46.24.png

其中首頁只展示7個(gè)功能入口减途,其余的入口用戶可以進(jìn)入去全部里面查看酣藻,且所有功能入口可拖拽排序,用戶可以根據(jù)自己的需要在首頁展示自己常用的功能鳍置。下面就給出該功能的實(shí)現(xiàn)思路辽剧。
這種九宮格的東西利用collectionView實(shí)現(xiàn)最簡單,對(duì)于iOS9.0以上系統(tǒng)税产,collectionView已支持拖拽排序怕轿,兩個(gè)代理方法即可:

func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool 
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) 
iOS9以下系統(tǒng)的實(shí)現(xiàn)思路:

1.給cell添加長按手勢

//
//  YRFunctionConfigCollectionViewCell.swift
//  YouRen
//
//  Created by MrZhaoCn on 2017/9/21.
//  Copyright ? 2017年 Zhou Shaolin. All rights reserved.
//

import UIKit
protocol YRFunctionConfigCollectionViewCellDelegate:NSObjectProtocol {
    func configButtonClik(view:YRFunctionConfigCollectionViewCell,id:Int32)
    func dragCellGestureAction(gesture:UIGestureRecognizer,id:Int32)
}
class YRFunctionConfigCollectionViewCell: UICollectionViewCell {
    
    @IBOutlet var configButton: UIButton!
    @IBOutlet var iconImageView: UIImageView!
    @IBOutlet var titleLabel: UILabel!
    @IBAction func configActionButtonClik(_ sender: Any) {
        guard let homeModel = homeModel else {
            return
        }
        delegate?.configButtonClik(view: self, id: homeModel.id)
    }
    weak var delegate:YRFunctionConfigCollectionViewCellDelegate?
    private var homeModel:YRHomeModuleModel?
    override func awakeFromNib() {
        super.awakeFromNib()
        //添加手勢
        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(gestureAction(gesture:)))
        self.addGestureRecognizer(longPress)
    }
    func gestureAction(gesture:UIGestureRecognizer) {
        guard let delegate = delegate else {
            return
        }
        guard let homeModel = homeModel else {
            return
        }
        delegate.dragSortCellGestureAction(gesture:gesture,id: homeModel.id)
    }
}

2.長按開始時(shí)截取cell視圖,并將視圖添加到collectionView上辟拷,并隱藏該cell

func dragCellGestureAction(gesture: UIGestureRecognizer,id:Int32) {
        //判斷是哪個(gè)collectionView
        var collectionView:UICollectionView = deleteCollectionView
        for item in deleteHomeModels {
            if item.id == id {
                collectionView = deleteCollectionView
                break
            }
        }
        for item in addHomeModels {
            if item.id == id {
                collectionView = addCollectionView
                break
            }
        }
        let point = gesture.location(in: collectionView)
        switch gesture.state {
        case UIGestureRecognizerState.began:
            dragBegan(gesture:gesture,point: point,collectionView:collectionView)
        case UIGestureRecognizerState.changed:
            drageChang(gesture: gesture,point: point, collectionView: collectionView)
        case UIGestureRecognizerState.ended:
            drageEnd(point: point, collectionView: collectionView)
        default: break
        }
    }
//MARK: - 長按開始
func dragBegan(gesture: UIGestureRecognizer,point: CGPoint,collectionView:UICollectionView) {
        indexPath = collectionView.indexPathForItem(at: point)
        if indexPath == nil {
            return
        }
        let item = collectionView.cellForItem(at: indexPath!) as? YRFunctionConfigCollectionViewCell
       //截取視圖
        self.snapItem = item?.snapshotView(afterScreenUpdates: true)
        self.snapItem?.center = (item?.center)!
        collectionView.addSubview(self.snapItem ?? UIView())
       //原cell隱藏
        item?.isHidden = true
        startPoint = gesture.location(in: collectionView)
    }

3.在拖拽過程中撞羽,根據(jù)手勢的位置,不斷調(diào)整截取視圖的位置,交換數(shù)據(jù)源.

//MARK: - 長按過程
  func drageChang(gesture: UIGestureRecognizer,point: CGPoint,collectionView:UICollectionView) {
        if indexPath == nil {
            return
        }
        let tranX = gesture.location(ofTouch: 0, in: collectionView).x - startPoint.x
        let tranY = gesture.location(ofTouch: 0, in: collectionView).y - startPoint.y
        //設(shè)置截圖視圖位置
        self.snapItem?.center = __CGPointApplyAffineTransform((self.snapItem?.center)!, CGAffineTransform(translationX: tranX, y: tranY))
        startPoint = gesture.location(ofTouch: 0, in: collectionView)
        targetIndexPath = collectionView.indexPathForItem(at: point)
        if targetIndexPath == nil {
            return
        }
        // 更新數(shù)據(jù)
        if collectionView == deleteCollectionView {
            let obj = deleteHomeModels[indexPath!.item]
            deleteHomeModels.remove(at: indexPath!.item)
            deleteHomeModels.insert(obj, at: targetIndexPath!.item)
        } else {
            let obj = addHomeModels[indexPath!.item]
            addHomeModels.remove(at: indexPath!.item)
            addHomeModels.insert(obj, at: targetIndexPath!.item)
        }
        //交換位置
        collectionView.moveItem(at: indexPath!, to: targetIndexPath!)
        indexPath = targetIndexPath
    }

4.手勢結(jié)束時(shí)獲取手勢的位置,并移除掉截取的視圖即可衫冻。

//MARK: - 長按結(jié)束
   func drageEnd(point: CGPoint,collectionView:UICollectionView) {
        if indexPath == nil {
            return
        }
        let endCell = collectionView.cellForItem(at: indexPath!)
        UIView.animate(withDuration: 0.25, animations: 
            self.snapItem?.center = (endCell?.center)!
        }, completion: {
            (finish) -> () in
            endCell?.isHidden = false
            self.snapItem?.removeFromSuperview()
            self.indexPath = nil
        })
    }

注:筆者的項(xiàng)目要求上面的功能刪除完時(shí)也要留有固定大小的區(qū)域同來添加功能诀紊,因此采用兩個(gè)collectionView實(shí)現(xiàn)隅俘,但思路是一樣的渡紫。其中deleteCollectionView為上面已添加的,deleteHomeModels為該數(shù)據(jù)源考赛。addCollectionView為待添加的惕澎,addHomeModels為其數(shù)據(jù)源。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末颜骤,一起剝皮案震驚了整個(gè)濱河市唧喉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖八孝,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件董朝,死亡現(xiàn)場離奇詭異,居然都是意外死亡干跛,警方通過查閱死者的電腦和手機(jī)子姜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來楼入,“玉大人哥捕,你說我怎么就攤上這事〖涡埽” “怎么了遥赚?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阐肤。 經(jīng)常有香客問我凫佛,道長,這世上最難降的妖魔是什么孕惜? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任愧薛,我火速辦了婚禮,結(jié)果婚禮上衫画,老公的妹妹穿的比我還像新娘毫炉。我一直安慰自己,他們只是感情好碧磅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布碘箍。 她就那樣靜靜地躺著,像睡著了一般鲸郊。 火紅的嫁衣襯著肌膚如雪丰榴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天秆撮,我揣著相機(jī)與錄音四濒,去河邊找鬼。 笑死职辨,一個(gè)胖子當(dāng)著我的面吹牛盗蟆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播舒裤,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼喳资,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了腾供?” 一聲冷哼從身側(cè)響起仆邓,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤鲜滩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后节值,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體徙硅,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年搞疗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嗓蘑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匿乃,死狀恐怖桩皿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扳埂,我是刑警寧澤业簿,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布瘤礁,位于F島的核電站阳懂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏柜思。R本人自食惡果不足惜岩调,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赡盘。 院中可真熱鬧号枕,春花似錦、人聲如沸陨享。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抛姑。三九已至赞厕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間定硝,已是汗流浹背皿桑。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔬啡,地道東北人诲侮。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像箱蟆,于是被迫代替她去往敵國和親沟绪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容