2017-09-24 4 views
0

Je crée 14 boutons par programmation dans une autre fonction et je leur ai ajouté une cible pour les animer tous, et j'ai des cibles quand j'appuie sur un bouton pour aller à la cible, mon problème comment revenir à la position d'origine en utilisantUIView.Animate??Retour du bouton à la position d'origine avec UIView.Animate

Exactement comme ce gifs:

Demo

Codes:

var tileArrayXAxis: [Int] = [] // X-Axis of the my 14 buttons 
var tileArrayYAxis: [Int] = [] // Y-Axis of the my 14 buttons 
var tileArrayWidth: [Int] = [] // Width of the my 14 buttons 
var tileArrayHeight: [Int] = [] // Heigh of the my 14 buttons 

var targetArrayXAxis: [Int] = [] // X-Axis of the target 
var targetArrayYAxis: [Int] = [] // Y-Axis of the target 
var targetArrayWidth: [Int] = [] // Width of the target 
var targetArrayHeight: [Int] = [] // Heigh of the target 

var i : Int = 0 

func moveButton(sender: UIButton) { 

    var xS = Int() 
    var yS = Int() 
    var widthS = Int() 
    var heightS = Int() 

    if i < targetArrayXAxis.count && i < targetArrayYAxis.count && i < targetArrayWidth.count && i < targetArrayHeight.count { 

     xS = targetArrayXAxis[i] 
     yS = targetArrayYAxis[i] 
     widthS = targetArrayWidth[i] 
     heightS = targetArrayHeight[i] 
     yS -= widthS 

     let startS = CGPoint(x: xS, y: yS) 

     let sizeS = CGSize(width: widthS, height: heightS) 
     sender.frame = CGRect(x: startS.x, y: startS.y, width: sizeS.width, height: sizeS.width) 

    } 

    UIView.animate(withDuration: 2, delay: 0, usingSpringWithDamping: 0.2, initialSpringVelocity: 6, options: .allowUserInteraction, animations: { [weak self] in 

     sender.transform = .identity 
     self?.i += 1   
    }) 
} 
+0

sender.transform = .identity ne pas revenir à la position d'origine? – Arrabidas92

+0

Non @ Arrabidas92 –

Répondre

0

Réglage transformation de l'identité une fois que vous avez défini le cadre d'une nouvelle valeur ne se déplace pas sur le bouton du tout, car il reviendra juste le nouveau cadre.

Soit: Vous devez stocker l'ancien cadre dans une variable, avant de vous mettre à une nouvelle valeur:

let oldFrame : CGRect = sender.frame 
// Now set the frame to its new value 
sender.frame = .... 

Et puis dans votre bloc d'animation:

sender.frame = oldFrame 

Ou: do n'attribuez pas de nouvelle image à l'expéditeur mais lui assignez une transformation de traduction, puis définissez la transformation sur identité dans le bloc d'animation pour annuler la transformation et renvoyer le bouton à l'endroit où il se trouvait.

EDIT: Comme l'a demandé, une implémentation simple de ViewController cela comme suit:

import UIKit 

classe ViewController: UIViewController {

fileprivate var buttonOne : UIButton! 
fileprivate var buttonTwo : UIButton! 
fileprivate var buttonOneFrame : CGRect { 
    return CGRect(origin: CGPoint(x: view.bounds.width/2 - 200, y: 100), 
    size: CGSize(width: 150, height: 100)) 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    buttonOne = { 
     let bO : UIButton = UIButton() 
     bO.backgroundColor = .red 
     bO.setTitle("Frame Method", for: .normal) 
     bO.addTarget(self, action: #selector(frameMethodMove(sender:)), for: .touchUpInside) 
     bO.frame = buttonOneFrame 
     return bO 
    }() 

    buttonTwo = { 
     let bT : UIButton = UIButton() 
     bT.backgroundColor = .blue 
     bT.setTitle("Transform Method", for: .normal) 
     bT.addTarget(self, action: #selector(transformMethodMove(sender:)), for: .touchUpInside) 
     bT.frame = CGRect(origin: CGPoint(x: view.bounds.width/2 + 50, y: 100), 
          size: CGSize(width: 150, height: 100)) 
     return bT 
    }() 

    view.addSubview(buttonOne) 
    view.addSubview(buttonTwo) 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

@objc fileprivate func frameMethodMove(sender: UIButton) -> Void { 

    let newFrame : CGRect = CGRect(origin: CGPoint(x: buttonOneFrame.origin.x, y: buttonOneFrame.origin.y + 500), 
            size: buttonOneFrame.size) 

    sender.frame = newFrame 

    sender.removeTarget(self, action: #selector(frameMethodMove(sender:)), for: .touchUpInside) 
    sender.addTarget(self, action: #selector(frameMethodMoveBack(sender:)), for: .touchUpInside) 
} 

@objc fileprivate func frameMethodMoveBack(sender: UIButton) -> Void { 

    UIView.animate(withDuration: 0.5, delay: 0, options: .allowUserInteraction, animations: { 
     sender.frame = self.buttonOneFrame 
    }, completion: ({ _ in 

     sender.removeTarget(self, action: #selector(self.frameMethodMoveBack(sender:)), for: .touchUpInside) 
     sender.addTarget(self, action: #selector(self.frameMethodMove(sender:)), for: .touchUpInside) 
    })) 

} 

@objc fileprivate func transformMethodMove(sender: UIButton) -> Void { 

    sender.transform = CGAffineTransform.init(translationX: 0, y: 500) 

    sender.removeTarget(self, action: #selector(transformMethodMove(sender:)), for: .touchUpInside) 
    sender.addTarget(self, action: #selector(transformMethodMoveBack(sender:)), for: .touchUpInside) 
} 

@objc fileprivate func transformMethodMoveBack(sender: UIButton) -> Void { 

    UIView.animate(withDuration: 0.5, delay: 0, options: .allowUserInteraction, animations: { 
     sender.transform = .identity 
    }, completion: ({ _ in 
     sender.removeTarget(self, action: #selector(self.transformMethodMoveBack(sender:)), for: .touchUpInside) 
     sender.addTarget(self, action: #selector(self.transformMethodMove(sender:)), for: .touchUpInside) 
    })) 
} 

}

+0

J'essaie votre solution, mais il est de retour à la position d'origine auto Je veux revenir à la position d'origine manuellement, je veux dire par appuyez sur, Comment puis-je faire cela ?? –

+0

S'il vous plaît regarder mon GIF et voir comment animation 4 boutons pour cibler et sauté position et revenir à leur position d'origine en appuyant sur leur @Sparky –

+0

@ user1.develop Je comprends ce que vous essayez de faire - retour des boutons avec un clic est trivial . Vous le faites en divisant les méthodes en deux, et en remplaçant les cibles de bouton. Pour la méthode du cadre, vous devez également enregistrer l'emplacement du bouton d'origine en tant que propriété de classe (que ce soit UIButton ou sous-classe); à mon avis, la méthode de transformation est probablement plus élégante. S'il vous plaît voir mon edit. – Sparky