Как анимировать пользовательский вид в пользовательский вид

Я создаю приложение, похожее на карточку, и использую библиотеку KolodaView: https://github.com/Yalantis/Koloda

У меня есть это расширение, которое возвращает UIView в качестве передней части карточки:

extension StudyViewController: KolodaViewDataSource {

func kolodaNumberOfCards(koloda:KolodaView) -> UInt {
    return UInt(memories.count)
}

func koloda(koloda: KolodaView, viewForCardAtIndex index: UInt) -> UIView {
    return UIImageView(image: memories[Int(index)].frontImage)
}

func koloda(koloda: KolodaView, viewForCardOverlayAtIndex index: UInt) -> OverlayView? {

    return NSBundle.mainBundle().loadNibNamed("OverlayView",owner: self, options: nil)[0] as? OverlayView
}
}

И я хочу иметь возможность преобразовать из вида в вид сзади одним касанием:

func koloda(koloda: KolodaView, didSelectCardAtIndex index: UInt) {

    let frontView: UIView = koloda as KolodaView
    let backView: UIView = UIImageView(image: memories[Int(index)].backImage)

    if showingFront == true {
        UIView.transitionFromView(frontView, toView: backView, duration: 1, options: UIViewAnimationOptions.TransitionCrossDissolve, completion: nil)
    } else {
        UIView.transitionFromView(backView, toView: frontView, duration: 1, options: UIViewAnimationOptions.TransitionCrossDissolve, completion: nil)
        showingFront = false
    }
}

Переход прошел успешно, но после его завершения карта памяти перестанет KolodaView гиганту UIView

Как мне преобразовать KolodaView пыльник KolodaView?

1 ответ

Я не пользовалась KolodaView поэтому мои ответы являются более общими для рассматриваемой проблемы.

Два подхода

а. Вариант вашего текущего подхода (хаккистский путь)

Поскольку библиотека не предоставляет ссылку на показанный imageView, вам сначала нужно будет сохранить свой внутренний набор imageView для последующего использования.

private var myImageViews: [Int: UIImageView] = [:]
func koloda(koloda: KolodaView, viewForCardAtIndex index: UInt) -> UIView {
    let imageView = UIImageView(image: memories[Int(index)].frontImage)
    myImageViews[Int(index)] = imageView
    return imageView
}

Анимируйте вид, используя текущий подход, и обновите конечное состояние исходного изображения, используя блок завершения.

UIView.transitionFromView(frontView,
                          toView: backView,
                          duration: duration,
                          options: [.TransitionCrossDissolve, .ShowHideTransitionViews],
                          completion: { [weak self] (finished: Bool) in
        let imageView = myImageViews[Int(index)]
        imageView.image = memories[Int(index)].frontImage
        frontView.hidden = false
        backView.hidden = true
        backView.removeFromSuperview()
})

б. Вернуть пользовательское представление в метод источника данных и переключить его внутреннее состояние в didSelectCardAtIndex

private var myCustomViews: [Int: MyCustomView] = [:]
func koloda(koloda: KolodaView, viewForCardAtIndex index: UInt) -> UIView {
    let customView = MyCustomView(frontImage: memories[Int(index)].frontImage, 
                                  backImage: memories[Int(index)].backImage)
    myCustomViews[Int(index)] = customView
    return customView
}

func koloda(koloda: KolodaView, didSelectCardAtIndex index: UInt) {
    let customView = myCustomViews[Int(index)]
    customView.toggleFrontBackState()
}

В этом случае реализация для toggleFrontBackState будет содержать код вашей начальной реализации (customView.showingFront, transitionFromView). Дайте мне знать, если вам нужно больше разъяснений.

РЕДАКТИРОВАТЬ

class MyCustomView: UIView {
    private(set) lazy var frontView: UIImageView = self.makeFrontView()
    private(set) lazy var backView: UIImageView = self.makeBackView()
    var showingFront: Bool = false

    init(frontImage: UIImage?, backImage: UIImage?){
        super.init(frame: CGRectZero)
        frontView.image = frontImage
        backView.image = backImage
        backView.hidden = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func toggleFrontBackState() {
        if showingFront {
            UIView.transitionFromView(frontView, toView: backView, duration: 1, 
                                      options: [.TransitionCrossDissolve, .ShowHideTransitionViews], completion: nil)
        } else {
            UIView.transitionFromView(backView, toView: frontView, duration: 1, 
                                      options: [.TransitionCrossDissolve, .ShowHideTransitionViews] , completion: nil)
        }
        showingFront = !showingFront
    }

    func makeFrontView() -> UIImageView {
        return UIImageView()
    }

    func makeBackView() -> UIImageView {
        return UIImageView()
    }
}
Другие вопросы по тегам