通过拖放重新排序 NSCollectionView 中的项目,swift 3+
Reorder items in NSCollectionView with drag and drop, swift 3+
我花了好几天时间尝试了很多不同的东西来完成这项工作,但总是失败。这开始变得令人沮丧,我真的很想知道如何让用户拖放工作以重新排序 NSCollectionView 中的项目的人的想法。
这是我最近的尝试,完全没有任何作用:
let MyItemType = "myItemType"
class CollectionViewController: NSViewController {
@IBOutlet weak var collectionView: NSCollectionView!
let MyItemType = "myItemType"
override func viewDidLoad() {
super.viewDidLoad()
configureCollectionView()
loadDevices()
getstate()
// try to register drag and drop (all attempts fail)
//collectionView.register(forDraggedTypes: [MyItemType, NSFilenamesPboardType]
}
// more functions here were omitted...
}
extension CollectionViewController : NSCollectionViewDataSource {
func numberOfSections(in collectionView: NSCollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return groupbuttons.count
}
func collectionView(_ itemForRepresentedObjectAtcollectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let item = collectionView.makeItem(withIdentifier: "CollectionViewItem", for: indexPath)
guard let collectionViewItem = item as? CollectionViewItem else {return item}
let button = groupbuttons[indexPath.item]
collectionViewItem.button = button
return item
}
/* try to implement drag and drop reordering (all attempts fail)
func collectionView(collectionView: NSCollectionView, canDragItemsAtIndexes indexes: NSIndexSet, withEvent event: NSEvent) -> Bool {
return true
}
func collectionView(_ collectionView: NSCollectionView, writeItemsAtIndexes indexes: NSIndexSet, to toPasteboard: NSPasteboard) -> Bool {
let data = NSKeyedArchiver.archivedData(withRootObject: [indexes])
toPasteboard.declareTypes([MyItemType], owner:self)
toPasteboard.setData(data, forType:MyItemType)
return true
}
func collectionView(_ collectionView: NSCollectionView, validateDrop info: NSDraggingInfo, proposedIndex index: Int, proposedDropOperation dropOperation: NSCollectionViewDropOperation) -> NSDragOperation {
//collectionView.setDropIndex(index, dropOperation: NSCollectionViewDropOperation.above)
return NSDragOperation.move
}
func collectionView(_ collectionView: NSCollectionView, acceptDrop info: NSDraggingInfo, index: Int, dropOperation: NSTableViewDropOperation) -> Bool {
let pasteboard = info.draggingPasteboard()
let itemData = pasteboard.data(forType: MyItemType)
if(itemData != nil) {
var dataArray = NSKeyedUnarchiver.unarchiveObject(with: itemData!) as! Array<IndexSet>,
indexSet = dataArray[0]
let movingFromIndex = indexSet.first
let item = groupbuttons[movingFromIndex!]
_moveItem(item, from: movingFromIndex!, to: index)
return true
}
else {
return false
}
}
func _moveItem(_ item: GroupButton, from: Int, to: Int) {
groupbuttons.remove(at: from)
if(to > groupbuttons.endIndex) {
groupbuttons.append(item)
}
else {
groupbuttons.insert(item, at: to)
}
collectionView.reloadData()
}
*/
}
如果有人能够使用 NSCollectionView 进行拖放重新排序,我将不胜感激。或者在这种情况下不可能?我不确定为什么拖放项目重新排序如此复杂。
我也遇到过同样的情况,终于知道怎么办了。这是我使用 Swift 4:
的代码
ViewDidLoad
var indiceItensMovidosDrag: Set<IndexPath> = []
override func viewDidLoad() {
super.viewDidLoad()
fotosProdutoLojaCollectionView.delegate = self
fotosProdutoLojaCollectionView.dataSource = self
fotosProdutoLojaCollectionView.registerForDraggedTypes([NSPasteboard.PasteboardType(kUTTypeItem as String)])
fotosProdutoLojaCollectionView.setDraggingSourceOperationMask(.move, forLocal: true)
if produtoLoja == nil {
produtoLoja = ProdutoLoja()
}
}
现在委托和数据源方法
func numberOfSections(in collectionView: NSCollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return produtoLoja!.fotos.count
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
var item = NSCollectionViewItem()
item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "FotoProdutoLojaCollectionViewItem"), for: indexPath)
let fotosProdutoLojaCollectionViewItem = item as! FotoProdutoLojaCollectionViewItem
produtoLoja?.fotos[indexPath.item].foto?.getDataInBackground(block: {
(data: Data?, error: Error?) -> Void in
if error == nil {
fotosProdutoLojaCollectionViewItem.fotoProdutoLojaImageView.image = NSImage(data: data!)
}
})
if produtoLoja!.fotos[indexPath.item].imagemCapa {
fotosProdutoLojaCollectionViewItem.fotoCapaImageView.isHidden = false
}else {
fotosProdutoLojaCollectionViewItem.fotoCapaImageView.isHidden = true
}
return item
}
func collectionView(_ collectionView: NSCollectionView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool {
return true
}
func collectionView(_ collectionView: NSCollectionView, pasteboardWriterForItemAt indexPath: IndexPath) -> NSPasteboardWriting? {
let retorno = NSPasteboardItem()
var data: Data?
do {
try data = produtoLoja?.fotos[indexPath.item].foto?.getData()
} catch {
}
retorno.setData(data!, forType: NSPasteboard.PasteboardType(kUTTypeItem as String))
return retorno
}
func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItemsAt indexPaths: Set<IndexPath>) {
indiceItensMovidosDrag = indexPaths
}
func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, dragOperation operation: NSDragOperation) {
indiceItensMovidosDrag = []
}
func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndexPath proposedDropIndexPath: AutoreleasingUnsafeMutablePointer<NSIndexPath>, dropOperation proposedDropOperation: UnsafeMutablePointer<NSCollectionView.DropOperation>) -> NSDragOperation {
if proposedDropOperation.pointee == NSCollectionView.DropOperation.on {
proposedDropOperation.pointee = NSCollectionView.DropOperation.before
}
return NSDragOperation.move
}
func collectionView(_ collectionView: NSCollectionView, acceptDrop draggingInfo: NSDraggingInfo, indexPath: IndexPath, dropOperation: NSCollectionView.DropOperation) -> Bool {
var retorno = true
if indiceItensMovidosDrag.count == 1 {
for indice in indiceItensMovidosDrag {
collectionView.animator().moveItem(at: indice, to: (indexPath.item <= indice.item) ? indexPath : (IndexPath(item: indexPath.item - 1, section: 0)))
}
} else {
mostrarErro(mensagem: "Erro", informativo: "Só é possível mover uma imagem por vez")
retorno = false
}
//fotosProdutoLojaCollectionView.reloadData()
return retorno
}
希望对您有所帮助
我花了好几天时间尝试了很多不同的东西来完成这项工作,但总是失败。这开始变得令人沮丧,我真的很想知道如何让用户拖放工作以重新排序 NSCollectionView 中的项目的人的想法。 这是我最近的尝试,完全没有任何作用:
let MyItemType = "myItemType"
class CollectionViewController: NSViewController {
@IBOutlet weak var collectionView: NSCollectionView!
let MyItemType = "myItemType"
override func viewDidLoad() {
super.viewDidLoad()
configureCollectionView()
loadDevices()
getstate()
// try to register drag and drop (all attempts fail)
//collectionView.register(forDraggedTypes: [MyItemType, NSFilenamesPboardType]
}
// more functions here were omitted...
}
extension CollectionViewController : NSCollectionViewDataSource {
func numberOfSections(in collectionView: NSCollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return groupbuttons.count
}
func collectionView(_ itemForRepresentedObjectAtcollectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
let item = collectionView.makeItem(withIdentifier: "CollectionViewItem", for: indexPath)
guard let collectionViewItem = item as? CollectionViewItem else {return item}
let button = groupbuttons[indexPath.item]
collectionViewItem.button = button
return item
}
/* try to implement drag and drop reordering (all attempts fail)
func collectionView(collectionView: NSCollectionView, canDragItemsAtIndexes indexes: NSIndexSet, withEvent event: NSEvent) -> Bool {
return true
}
func collectionView(_ collectionView: NSCollectionView, writeItemsAtIndexes indexes: NSIndexSet, to toPasteboard: NSPasteboard) -> Bool {
let data = NSKeyedArchiver.archivedData(withRootObject: [indexes])
toPasteboard.declareTypes([MyItemType], owner:self)
toPasteboard.setData(data, forType:MyItemType)
return true
}
func collectionView(_ collectionView: NSCollectionView, validateDrop info: NSDraggingInfo, proposedIndex index: Int, proposedDropOperation dropOperation: NSCollectionViewDropOperation) -> NSDragOperation {
//collectionView.setDropIndex(index, dropOperation: NSCollectionViewDropOperation.above)
return NSDragOperation.move
}
func collectionView(_ collectionView: NSCollectionView, acceptDrop info: NSDraggingInfo, index: Int, dropOperation: NSTableViewDropOperation) -> Bool {
let pasteboard = info.draggingPasteboard()
let itemData = pasteboard.data(forType: MyItemType)
if(itemData != nil) {
var dataArray = NSKeyedUnarchiver.unarchiveObject(with: itemData!) as! Array<IndexSet>,
indexSet = dataArray[0]
let movingFromIndex = indexSet.first
let item = groupbuttons[movingFromIndex!]
_moveItem(item, from: movingFromIndex!, to: index)
return true
}
else {
return false
}
}
func _moveItem(_ item: GroupButton, from: Int, to: Int) {
groupbuttons.remove(at: from)
if(to > groupbuttons.endIndex) {
groupbuttons.append(item)
}
else {
groupbuttons.insert(item, at: to)
}
collectionView.reloadData()
}
*/
}
如果有人能够使用 NSCollectionView 进行拖放重新排序,我将不胜感激。或者在这种情况下不可能?我不确定为什么拖放项目重新排序如此复杂。
我也遇到过同样的情况,终于知道怎么办了。这是我使用 Swift 4:
的代码ViewDidLoad
var indiceItensMovidosDrag: Set<IndexPath> = []
override func viewDidLoad() {
super.viewDidLoad()
fotosProdutoLojaCollectionView.delegate = self
fotosProdutoLojaCollectionView.dataSource = self
fotosProdutoLojaCollectionView.registerForDraggedTypes([NSPasteboard.PasteboardType(kUTTypeItem as String)])
fotosProdutoLojaCollectionView.setDraggingSourceOperationMask(.move, forLocal: true)
if produtoLoja == nil {
produtoLoja = ProdutoLoja()
}
}
现在委托和数据源方法
func numberOfSections(in collectionView: NSCollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return produtoLoja!.fotos.count
}
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
var item = NSCollectionViewItem()
item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "FotoProdutoLojaCollectionViewItem"), for: indexPath)
let fotosProdutoLojaCollectionViewItem = item as! FotoProdutoLojaCollectionViewItem
produtoLoja?.fotos[indexPath.item].foto?.getDataInBackground(block: {
(data: Data?, error: Error?) -> Void in
if error == nil {
fotosProdutoLojaCollectionViewItem.fotoProdutoLojaImageView.image = NSImage(data: data!)
}
})
if produtoLoja!.fotos[indexPath.item].imagemCapa {
fotosProdutoLojaCollectionViewItem.fotoCapaImageView.isHidden = false
}else {
fotosProdutoLojaCollectionViewItem.fotoCapaImageView.isHidden = true
}
return item
}
func collectionView(_ collectionView: NSCollectionView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool {
return true
}
func collectionView(_ collectionView: NSCollectionView, pasteboardWriterForItemAt indexPath: IndexPath) -> NSPasteboardWriting? {
let retorno = NSPasteboardItem()
var data: Data?
do {
try data = produtoLoja?.fotos[indexPath.item].foto?.getData()
} catch {
}
retorno.setData(data!, forType: NSPasteboard.PasteboardType(kUTTypeItem as String))
return retorno
}
func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItemsAt indexPaths: Set<IndexPath>) {
indiceItensMovidosDrag = indexPaths
}
func collectionView(_ collectionView: NSCollectionView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, dragOperation operation: NSDragOperation) {
indiceItensMovidosDrag = []
}
func collectionView(_ collectionView: NSCollectionView, validateDrop draggingInfo: NSDraggingInfo, proposedIndexPath proposedDropIndexPath: AutoreleasingUnsafeMutablePointer<NSIndexPath>, dropOperation proposedDropOperation: UnsafeMutablePointer<NSCollectionView.DropOperation>) -> NSDragOperation {
if proposedDropOperation.pointee == NSCollectionView.DropOperation.on {
proposedDropOperation.pointee = NSCollectionView.DropOperation.before
}
return NSDragOperation.move
}
func collectionView(_ collectionView: NSCollectionView, acceptDrop draggingInfo: NSDraggingInfo, indexPath: IndexPath, dropOperation: NSCollectionView.DropOperation) -> Bool {
var retorno = true
if indiceItensMovidosDrag.count == 1 {
for indice in indiceItensMovidosDrag {
collectionView.animator().moveItem(at: indice, to: (indexPath.item <= indice.item) ? indexPath : (IndexPath(item: indexPath.item - 1, section: 0)))
}
} else {
mostrarErro(mensagem: "Erro", informativo: "Só é possível mover uma imagem por vez")
retorno = false
}
//fotosProdutoLojaCollectionView.reloadData()
return retorno
}
希望对您有所帮助