web-dev-qa-db-ja.com

iOS-カード反転アニメーション

2つのUIImageViewがあります。 1つは「フロント」、もう1つは「バック」です。私が実装しようとしているのは、「戻る」をクリックするとアニメーションがトリガーされ、カードが反転するようにするためです。

アニメーションは完全に機能します。しかし、それは私が望まないページ全体をアニメーション化します。 UIImageViewを反転させたいだけです。何が悪いのかわかりません。おそらく明白な何か。

@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
    }
}
12
Scott B

あなたの問題はあなたのUIImageViewsが直接「全ページ」ビューにあるということです。

transitionFromViewは、スーパービューからfromViewを削除し、指定されたアニメーションでスーパービューにtoViewを追加します。したがって、それはスーパービューをアニメーション化します。

コンテナーとして機能するUIViewを含め、両方のimageViewをサブビューとして含める必要があります。コンテナービューにタップジェスチャーを追加します。また、imageViewsへの弱い参照があってはなりません。一度アニメーションを実行すると、背面のimageViewへの参照がなくなるためです。ストーリーボードではなく、コードでこれらを追加する方が良いでしょう。 imageViewsを非表示にする必要はありません。

ここにいくつかのサンプルコードがあります:

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
        }   

    }
12
Carien van Zyl

変数として「カード」を保持するbuttonがあり、彼の画像を「1」という新しい画像に変更したい場合。あなたがしなければならないすべてはこれです:

let image = UIImage(named: "1")
card.setImage(image, for: .normal)
UIView.transition(with: card, duration: 2, options: .transitionFlipFromRight, animations: nil, completion: nil)
9
J. Doe

このソリューションは、2つのUIImageViewを使用して「カード」を反転するためのものです(使用しているように...)、UICollectionView内で使用しています。もちろん、それは必要ではありません。

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
        }
    }
}

コードは私の- オープンソースプロジェクトから引用していますSwift開発、SwiftIntroと呼ばれますメモリゲーム、 Instagramから画像を取得しています。

モデルカードはクラスであり、値タイプではないことに注意してください

4
Sajjon

コンテナビューが必要です。 answerImageViewerbackAnswerImageViewerを1つのUIViewに入れます。これが私のサンプルコードです。

    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)
3
wint

パンカジの答えによると、

IOS 12では、UIView.transitionメソッドの使用は少し推奨されていません。

IOS 12デバイスでは、コードをSwift 4.0からSwift 4.2に)更新しましたが、カードをめくる問題が発生しました。

あなたはこれを間違えるかもしれません。どういうわけか、Xcodeはこれを変更することを提案していません。 UIView.transitionメソッドを書き直そうとしたときに、(Intellisenseのおかげで)これに気付きました。

前:

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
    })

後:

 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:これら2つのコードはすべて私の場合のものです。貼り付けをコピーしないでください。

誰かの命を救えることを願っています。

1
Oliver

Swift 4

UIImageViewではなくUIButtonを使用するのが最善です!

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)
}

この答えが役に立てば幸い:)!

1
Sree Ramana

このコードを使用できます

UIView.transition(with:self.yourViewName、duration:0.5、options:[.transitionFlipFromRight]、animations:nil、completion:nil)

0
Pankaj Jangid

この拡張機能を試してください。多分使いやすいかもしれません

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
        }
    }
}

これをクリックアクションで使用する

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()
        }
}
0