gpt4 book ai didi

swift - 自定义拖放 UICollectionViewLayout 捕捉到网格

转载 作者:行者123 更新时间:2023-11-28 06:02:52 34 4
gpt4 key购买 nike

我正在开发一个应用程序,我可以在其中跟踪我的青年足球队的替补情况。

遵循 Payal Gupta 的教程在拖放到集合和表格中时,我设法在两个 Collection View (PlayersOntoTheField 和 Substitutes)之间进行拖放工作 Screenshot .

当我将一名替补球员拖到我的 Playground 上时,它现在应该会捕捉到预定义的球队阵容(例如屏幕截图中的 3-2-1)。是否可以通过自定义 UICollectionViewLayout 获得此类行为,或者有人有其他建议吗?

非常感谢您的帮助。

丹尼

//Based on a work by: 
//Payal Gupta (https://github.com/pgpt10/DragAndDrop-CollectionView)

import UIKit

class ViewController: UIViewController
{
private var substitutes = ["player1", "player2", "player3", "player4"]
private var players = [String]()

@IBOutlet weak var substitutesCollectionView: UICollectionView!
@IBOutlet weak var playersCollectionView: UICollectionView!

override func viewDidLoad()
{
super.viewDidLoad()

//SubstitutesCollectionView drag and drop configuration
self.substitutesCollectionView.dragInteractionEnabled = true
self.substitutesCollectionView.dragDelegate = self
self.substitutesCollectionView.dropDelegate = self

//PlayersCollectionView drag and drop configuration
self.playersCollectionView.dragInteractionEnabled = true
self.playersCollectionView.dropDelegate = self
self.playersCollectionView.dragDelegate = self
self.playersCollectionView.reorderingCadence = .fast //default value - .immediate
}

//MARK: Private Methods
private func reorderItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView)
{
let items = coordinator.items
if items.count == 1, let item = items.first, let sourceIndexPath = item.sourceIndexPath
{
var dIndexPath = destinationIndexPath
if dIndexPath.row >= collectionView.numberOfItems(inSection: 0)
{
dIndexPath.row = collectionView.numberOfItems(inSection: 0) - 1
}
collectionView.performBatchUpdates({
if collectionView === self.playersCollectionView
{
self.players.remove(at: sourceIndexPath.row)
self.players.insert(item.dragItem.localObject as! String, at: dIndexPath.row)
}
else
{
self.substitutes.remove(at: sourceIndexPath.row)
self.substitutes.insert(item.dragItem.localObject as! String, at: dIndexPath.row)
}
collectionView.deleteItems(at: [sourceIndexPath])
collectionView.insertItems(at: [dIndexPath])
})
coordinator.drop(items.first!.dragItem, toItemAt: dIndexPath)
}
}

private func copyItems(coordinator: UICollectionViewDropCoordinator, destinationIndexPath: IndexPath, collectionView: UICollectionView)
{
collectionView.performBatchUpdates({
var indexPaths = [IndexPath]()
for (index, item) in coordinator.items.enumerated()
{
let indexPath = IndexPath(row: destinationIndexPath.row + index, section: destinationIndexPath.section)
if collectionView === self.playersCollectionView
{
self.players.insert(item.dragItem.localObject as! String, at: indexPath.row)
}
else
{
self.substitutes.insert(item.dragItem.localObject as! String, at: indexPath.row)
}
indexPaths.append(indexPath)
}
collectionView.insertItems(at: indexPaths)
})
}
}

// MARK: - UICollectionViewDataSource Methods
extension ViewController : UICollectionViewDataSource
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return collectionView == self.substitutesCollectionView ? self.substitutes.count : self.players.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
if collectionView == self.substitutesCollectionView
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell1", for: indexPath) as! MyCollectionViewCell
cell.customImageView?.image = UIImage(named: self.substitutes[indexPath.row])
cell.customLabel.text = self.substitutes[indexPath.row].capitalized
return cell
}
else
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell2", for: indexPath) as! MyCollectionViewCell
cell.customImageView?.image = UIImage(named: self.players[indexPath.row])
cell.customLabel.text = self.players[indexPath.row].capitalized
return cell
}
}
}

// MARK: - UICollectionViewDragDelegate Methods
extension ViewController : UICollectionViewDragDelegate
{
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem]
{
let item = collectionView == substitutesCollectionView ? self.substitutes[indexPath.row] : self.players[indexPath.row]
let itemProvider = NSItemProvider(object: item as NSString)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = item
return [dragItem]
}

func collectionView(_ collectionView: UICollectionView, itemsForAddingTo session: UIDragSession, at indexPath: IndexPath, point: CGPoint) -> [UIDragItem]
{
let item = collectionView == substitutesCollectionView ? self.substitutes[indexPath.row] : self.players[indexPath.row]
let itemProvider = NSItemProvider(object: item as NSString)
let dragItem = UIDragItem(itemProvider: itemProvider)
dragItem.localObject = item
return [dragItem]
}

func collectionView(_ collectionView: UICollectionView, dragPreviewParametersForItemAt indexPath: IndexPath) -> UIDragPreviewParameters?
{
if collectionView == substitutesCollectionView
{
let previewParameters = UIDragPreviewParameters()
previewParameters.visiblePath = UIBezierPath(rect: CGRect(x: 15, y: 5, width: 30, height: 30))
return previewParameters
}
return nil
}
}

// MARK: - UICollectionViewDropDelegate Methods
extension ViewController : UICollectionViewDropDelegate
{
func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool
{
return session.canLoadObjects(ofClass: NSString.self)
}

func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal
{
if collectionView === self.substitutesCollectionView
{
if collectionView.hasActiveDrag
{
return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}
else
{
return UICollectionViewDropProposal(operation: .forbidden)
}
}
else
{
if collectionView.hasActiveDrag
{
return UICollectionViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}
else
{
return UICollectionViewDropProposal(operation: .copy, intent: .insertAtDestinationIndexPath)
}
}
}

func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator)
{
let destinationIndexPath: IndexPath
if let indexPath = coordinator.destinationIndexPath
{
destinationIndexPath = indexPath
}
else
{
// Get last index path of table view.
let section = collectionView.numberOfSections - 1
let row = collectionView.numberOfItems(inSection: section)
destinationIndexPath = IndexPath(row: row, section: section)
}

switch coordinator.proposal.operation
{
case .move:
self.reorderItems(coordinator: coordinator, destinationIndexPath:destinationIndexPath, collectionView: collectionView)
break

case .copy:
self.copyItems(coordinator: coordinator, destinationIndexPath: destinationIndexPath, collectionView: collectionView)

default:
return
}
}
}

最佳答案

到目前为止,我对自定义 UICollectionViewLayout 的解决方法是:

import UIKit

class LineUp_3_2_1View: UICollectionViewLayout {

private var center: CGPoint!
private var itemSize: CGSize!
private var radiusOfCircleViews: CGFloat!
private var numberOfItems: Int!

override func prepare() {
super.prepare()

guard let collectionView = collectionView else { return }

radiusOfCircleViews = CGFloat(30.0)
itemSize = CGSize(width: radiusOfCircleViews * 2, height: radiusOfCircleViews * 2)
center = CGPoint(x: collectionView.bounds.midX, y: collectionView.bounds.midY)
numberOfItems = collectionView.numberOfItems(inSection: 0)
}

override var collectionViewContentSize: CGSize {
return collectionView!.bounds.size
}

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)

if (indexPath.item == 0) {attributes.center = CGPoint(x: 169, y: 344)}
if (indexPath.item == 1) {attributes.center = CGPoint(x: 46, y: 250)}
if (indexPath.item == 2) {attributes.center = CGPoint(x: 169, y: 250)}
if (indexPath.item == 3) {attributes.center = CGPoint(x: 287, y: 250)}
if (indexPath.item == 4) {attributes.center = CGPoint(x: 80, y: 156)}
if (indexPath.item == 5) {attributes.center = CGPoint(x: 253, y: 156)}
if (indexPath.item == 6) {attributes.center = CGPoint(x: 169, y: 62)}

attributes.size = itemSize

return attributes
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
return (0 ..< collectionView!.numberOfItems(inSection: 0))
.flatMap { item -> UICollectionViewLayoutAttributes? in // `compactMap` in Xcode 9.3
self.layoutAttributesForItem(at: IndexPath(item: item, section: 0))
}
}
}

关于swift - 自定义拖放 UICollectionViewLayout 捕捉到网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49083273/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com