Как повернуть предварительный просмотр Drag&Drop в Swift
У меня проблема с поворотом предварительного просмотра при перетаскивании кнопки. В этом проекте я перетаскиваю кнопку, представляющую улицу, которую вы можете вращать, поэтому, когда пользователь поворачивает кнопку, я сохраняю количество поворотов в теге кнопки. Я пытался использовать методы UITargetedDragPreview и поставщика предварительного просмотра элемента перетаскивания, но это не сработало. Мой подход неверен?
Это код (в последних трех методах есть подходы, которые я пробовал:
func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
if let btn=self.cardsStack.hitTest(session.location(in: self.cardsStack), with: nil) as? UIButton{
let touchedImage=btn.currentBackgroundImage ?? UIImage()
selectedCard = (touchedImage, btn.tag)
let itemProvider=NSItemProvider(object: touchedImage)
let dragItem=UIDragItem(itemProvider: itemProvider)
selectedBtn=btn
return [dragItem]
}
else{
return []
}
}
func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
return UIDropProposal(operation: .copy)
}
func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
for dragItem in session.items {
dragItem.itemProvider.loadObject(ofClass: UIImage.self, completionHandler: {object,error in
DispatchQueue.main.async {
if let btn=self.outerStack.hitTest(session.location(in: self.outerStack), with: nil) as? UIButton{
btn.setTitle("", for: .normal)
btn.setBackgroundImage(self.selectedCard.0, for: .normal)
btn.transform=CGAffineTransform(rotationAngle: (.pi/2)*CGFloat(self.selectedCard.1))
let result=self.handler.addCard(at: self.buttonAt(btn: btn)!, to: self.directions(for: self.selectedCard.0, rotations: self.selectedCard.1), in: self.structure(for: self.selectedCard.0), for: self.selectedCard.1)
self.selectedCard=(UIImage(),0)
self.selectedBtn.transform=CGAffineTransform(rotationAngle: 0)
UIView.animate(withDuration: 0.5, animations: {
self.selectedBtn.transform=self.selectedBtn.transform.translatedBy(x: 0, y: self.outerStack.frame.maxY)
}, completion: {_ in
UIView.animate(withDuration: 1, animations: {
self.selectedBtn.transform=CGAffineTransform.identity
self.selectedBtn.setBackgroundImage(UIImage(named: self.cardsDeck[0]), for: .normal)
})
self.selectedBtn.tag=0
self.cardsDeck.removeFirst()
})
self.handler.indexActivePlayer = self.handler.indexActivePlayer>=self.handler.players.count-1 ? 0 : self.handler.indexActivePlayer+1
let index=self.handler.indexActivePlayer
self.turnButton.tintColor=self.handler.players[index].exitColor
self.turnButton.title=self.handler.players[index].nickname
if let exit = result{
self.win=true
self.winnerExit=exit
self.performSegue(withIdentifier: "result", sender: nil)
}
}
}
})
}
}
func canDrop(for btn:UIButton)->Bool{
let image=selectedCard.0
let rotations=selectedCard.1
let position=buttonAt(btn: btn)!
if btn.currentBackgroundImage != nil{
return false
}
else{
let directions=directions(for: image, rotations: rotations)
var index=0 //punti in cui la strada si può collegare
var t=false //valore che segnala se è posizionabile in tutte le direzioni in cui c'è qualcosa
let dir:[Direction]=[.left, .right, .top, .bottom]
for d in dir{
switch d {
case .left:
if directions.contains(.left){
if handler.streetsTable[position.section][position.row-1].structure[2]>0{
t=true
index+=1
}
else if handler.streetsTable[position.section][position.row-1].structure.allSatisfy({$0<0}){
index+=1
}
}
else if handler.streetsTable[position.section][position.row-1].structure[2]<0{
index+=1 //rileva se la strada a sinistra non è vuota
}
case .top:
if directions.contains(.top){
if handler.streetsTable[position.section-1][position.row].structure[3]>0{
t=true
index+=1
}
else if handler.streetsTable[position.section-1][position.row].structure.allSatisfy({$0<0}){
index+=1
}
}
else if handler.streetsTable[position.section-1][position.row].structure[3]<0{
index+=1
}
case .right:
if directions.contains(.right){
if handler.streetsTable[position.section][position.row+1].structure[0]>0{
t=true
index+=1
}
else if handler.streetsTable[position.section][position.row+1].structure.allSatisfy({$0<0}){
index+=1
}
}
else if handler.streetsTable[position.section][position.row+1].structure[0]<0{
index+=1
}
case .bottom:
if directions.contains(.bottom){
if handler.streetsTable[position.section+1][position.row].structure[1]>0{
t=true
index+=1
}
else if handler.streetsTable[position.section+1][position.row].structure.allSatisfy({$0<0}){
index+=1
}
}
else if handler.streetsTable[position.section+1][position.row].structure[1]<0{
index+=1
}
}
}
t=t&&index==4
return t
}
}
func dragInteraction(_ interaction: UIDragInteraction, sessionIsRestrictedToDraggingApplication session: UIDragSession) -> Bool {
return true
}
func dragInteraction(_ interaction: UIDragInteraction, prefersFullSizePreviewsFor session: UIDragSession) -> Bool {
return false
}
func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
if let btn=outerStack.hitTest(session.location(in: outerStack), with: nil) as? UIButton{
return session.canLoadObjects(ofClass: UIImage.self) && canDrop(for: btn)
}
else{
return false
}
}
func dragInteraction(_ interaction: UIDragInteraction, sessionDidMove session: UIDragSession) {
session.items[0].previewProvider = {
let imageView = UIImageView(frame: self.selectedBtn.frame)
imageView.transform = CGAffineTransform(rotationAngle: .pi/2 * CGFloat(self.selectedCard.1))
imageView.image=self.selectedCard.0
return UIDragPreview(view: imageView)
}
}
func dropInteraction(_ interaction: UIDropInteraction, previewForDropping item: UIDragItem, withDefault defaultPreview: UITargetedDragPreview) -> UITargetedDragPreview? {let parameters=UIPreviewParameters()
parameters.visiblePath=UIBezierPath(rect: selectedBtn.frame)
parameters.shadowPath=UIBezierPath(rect: selectedBtn.frame)
let target=UIPreviewTarget(container: selectedBtn, center: selectedBtn.center, transform: selectedBtn.transform)
return UITargetedDragPreview(view: selectedBtn, parameters: parameters, target: target)
}
func dragInteraction(_ interaction: UIDragInteraction, previewForLifting item: UIDragItem, session: UIDragSession) -> UITargetedDragPreview? {
let parameters=UIPreviewParameters()
let w=selectedBtn.frame.width/2
let h=selectedBtn.frame.height/2
let x=selectedBtn.frame.midX
let y=selectedBtn.frame.midY
parameters.visiblePath=UIBezierPath(rect: CGRect(x: x, y: y, width: w, height: h) )
selectedBtn.adjustsImageSizeForAccessibilityContentSizeCategory=true
let target=UIPreviewTarget(container: cardsStack, center: selectedBtn.center)
return UITargetedDragPreview(view: selectedBtn, parameters: parameters, target: target)
}