J'ai deux UIImageViews. L'un est le "Front" et l'autre le "Retour" ... Je tente de le mettre en œuvre de sorte que lorsque vous cliquez sur le "Retour", l'animation se déclenche et la carte est retournée.
L'animation fonctionne parfaitement. Mais cela anime la page entière, ce que je ne veux pas. Je veux seulement que la UIImageView
retourne. Je ne vois pas ce que je fais mal. Probablement quelque chose d'évident.
@IBOutlet weak var answerImageViewer: UIImageView?
@IBOutlet weak var backAnswerImageViewer: UIImageView?
override func viewDidLoad() {
super.viewDidLoad()
startNewGame()
retrieveNewQuestion()
setupBannerMessage()
customPlayButtons()
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("tap"))
tapGesture.numberOfTapsRequired = 1
backAnswerImageViewer?.addGestureRecognizer(tapGesture)
backAnswerImageViewer?.userInteractionEnabled = true
}
var showingBack = true
func tap (){
if showingBack{
UIView.transitionFromView(self.backAnswerImageViewer!, toView: self.answerImageViewer!, duration: 1, options: UIViewAnimationOptions.TransitionFlipFromRight, completion: nil)
backAnswerImageViewer?.hidden = true
answerImageViewer?.hidden = false
showingBack = false
}
else {
showingBack = true
UIView.transitionFromView(self.answerImageViewer!, toView: self.backAnswerImageViewer!, duration: 1, options: UIViewAnimationOptions.TransitionFlipFromRight, completion: nil)
backAnswerImageViewer?.hidden = false
answerImageViewer?.hidden = true
}
}
Votre problème est que vos UIImageViews sont directement sur la vue "page entière".
transitionFromView supprime le fromView de sa vue d'ensemble et ajoute le toView sur la vue d'ensemble avec l'animation donnée. Ainsi, il anime la superview.
Vous devez inclure un UIView qui serveurs en tant que conteneur et avoir les deux imageViews en tant que sous-vues. Ajoutez votre geste sur la vue d'ensemble. De plus, vous ne devriez pas avoir de faibles références aux images imageViews, car une fois que vous avez terminé l’animation, votre référence à l’image imageView précédente disparaîtra. Il est probablement préférable d’ajouter ces éléments dans le code plutôt que dans le scénario. Pas besoin de cacher les imageViews.
Voici quelques exemples de code:
class MyViewController: UIViewController {
@IBOutlet weak var containerView: UIView!
private let backImageView: UIImageView! = UIImageView(image: UIImage(named: "back"))
private let frontImageView: UIImageView! = UIImageView(image: UIImage(named: "front"))
private var showingBack = false
override func viewDidLoad() {
super.viewDidLoad()
frontImageView.contentMode = .ScaleAspectFit
backImageView.contentMode = .ScaleAspectFit
containerView.addSubview(frontImageView)
frontImageView.translatesAutoresizingMaskIntoConstraints = false
frontImageView.spanSuperview()
let singleTap = UITapGestureRecognizer(target: self, action: #selector(flip))
singleTap.numberOfTapsRequired = 1
containerView.addGestureRecognizer(singleTap)
}
func flip() {
let toView = showingBack ? frontImageView : backImageView
let fromView = showingBack ? backImageView : frontImageView
UIView.transitionFromView(fromView, toView: toView, duration: 1, options: .TransitionFlipFromRight, completion: nil)
toView.translatesAutoresizingMaskIntoConstraints = false
toView.spanSuperview()
showingBack = !showingBack
}
}
Si vous avez une button
qui contient "carte" comme variable et que vous voulez changer son image en une nouvelle image appelée "1". Tout ce que vous avez à faire est ceci:
let image = UIImage(named: "1")
card.setImage(image, for: .normal)
UIView.transition(with: card, duration: 2, options: .transitionFlipFromRight, animations: nil, completion: nil)
Cette solution permet de retourner "une carte", en utilisant deux UIImageView
(comme vous utilisez ...), je l’utilise dans un UICollectionView, ce qui n’est bien sûr pas nécessaire.
class CardCVCell: UICollectionViewCell {
@IBOutlet weak var cardFrontImageView: UIImageView!
@IBOutlet weak var cardBackImageView: UIImageView!
private var flipped: Bool = false {
didSet {
cardFrontImageView.visible = flipped
cardBackImageView.hidden = flipped
}
}
override func awakeFromNib() {
super.awakeFromNib()
cardBackImageView.backgroundColor = UIColor.brownColor()
}
override func prepareForReuse() {
super.prepareForReuse()
cardFrontImageView.image = nil
flipped = false
}
func flipCard(cardModel: Card) {
let flipped = cardModel.flipped
let fromView = flipped ? cardFrontImageView : cardBackImageView
let toView = flipped ? cardBackImageView : cardFrontImageView
let flipDirection: UIViewAnimationOptions = flipped ? .TransitionFlipFromRight : .TransitionFlipFromLeft
let options: UIViewAnimationOptions = [flipDirection, .ShowHideTransitionViews]
UIView.transitionFromView(fromView, toView: toView, duration: 0.6, options: options) {
finished in
cardModel.flipped = !flipped
}
}
}
Le code provient de mon projet open source présentant le développement Swift, appelé SwiftIntro , qui est un jeu de mémoire, récupérant des images sur Instagram.
Veuillez noter que le modèle de carte doit être une classe et non un type de valeur
Vous devez avoir une vue de conteneur. Mettez answerImageViewer
et backAnswerImageViewer
en un seul UIView
. Voici mon exemple de code.
let frontView = UIView()
let backView = UIView()
let frame = CGRect(x: 40, y: 100, width: 300, height: 400)
frontView.backgroundColor = .red
backView.backgroundColor = .blue
frontView.frame = CGRect(x: 0, y: 0, width: 300, height: 400)
backView.frame = CGRect(x: 0, y: 0, width: 300, height: 400)
let containerView = UIView()
containerView.frame = frame
containerView.addSubview(backView)
containerView.addSubview(frontView)
view.addSubview(containerView)
Selon la réponse de Pankaj,
Dans iOS 12, l’utilisation de la méthode UIView.transition est un peu obsolète.
Sur l'appareil iOS 12, bien que j'ai mis à jour le code de Swift 4.0 à Swift 4.2, j'ai rencontré un problème de retournement de carte.
Vous pourriez mal comprendre cela parce que; En quelque sorte, Xcode ne suggère pas de changer cela. J'ai compris cela (grâce à Intellisense) en essayant de réécrire la méthode UIView.transition.
Avant:
UIView.transition(with: cardView, duration: 1.0, options: transitionOptions, animations: {
self.cardView.isHidden = true
self.downButtonForBackCard.alpha = 1
})
UIView.transition(with: backCardView, duration: 1.0, options: transitionOptions, animations: {
self.backCardView.isHidden = false
})
Après:
UIView.transition(with: cardView, duration: 1.0, options: transitionOptions, animations: {
self.downButtonForBackCard.alpha = 1
}) { (finish) in
self.cardView.isHidden = true
}
UIView.transition(with: backCardView, duration: 1.0, options: transitionOptions, animations: {
self.backCardView.isHidden = false
}) { (finish) in
}
PS: Ces deux codes sont tous de mon cas. Ne pas copier coller, juste prendre exemple.
J'espère pouvoir sauver la vie de quelqu'un.
Pour Swift 4
Il est préférable d’utiliser UIButton plutôt que UIImageView!
var isBackImageOpen = false
if isBackImageOpen {
isBackImageOpen = false
let image = UIImage(named: "backImage")
myBtn.setImage(image, for: .normal)
UIView.transition(with: myBtn, duration: 0.3, options: .transitionFlipFromLeft, animations: nil, completion: nil)
} else {
isBackImageOpen = true
let image = UIImage(named: "frontImage")
myBtn.setImage(image, for: .normal)
UIView.transition(with: myBtn, duration: 0.3, options: .transitionFlipFromRight, animations: nil, completion: nil)
}
J'espère que cette réponse aide :)!
Vous pouvez utiliser ce code
UIView.transition (avec: self.yourViewName, durée: 0,5, options: [.transitionFlipFromRight], animations: nil, complétion: nil)
Essayez cette extension peut-être qu'il est facile à utiliser
extension UIView{
func showFlip(){
if self.isHidden{
UIView.transition(with: self, duration: 1, options: [.transitionFlipFromRight,.allowUserInteraction], animations: nil, completion: nil)
self.isHidden = false
}
}
func hideFlip(){
if !self.isHidden{
UIView.transition(with: self, duration: 1, options: [.transitionFlipFromLeft,.allowUserInteraction], animations: nil, completion: nil)
self.isHidden = true
}
}
}
utiliser cette action de clic
func Flip(){
if second_view.isHidden == true{
second_view.showFlip()
first_view.hideFlip()
}else if first_view.isHidden == true{
second_view.hideFlip()
first_view.showFlip()
}
}