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