如何将自定义视图动画化为自定义视图
Posted
技术标签:
【中文标题】如何将自定义视图动画化为自定义视图【英文标题】:How to animate a custom view to a custom view 【发布时间】:2016-08-09 11:34:16 【问题描述】:我正在构建一个类似抽认卡的应用程序,并且我正在使用库 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
,所以我的回答对于手头的问题更为通用。
两种方法
一个。您当前方法的变体(Hackish 方式)
由于库不公开对所示 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()
)
b.在 datasource 方法中返回一个自定义视图,并在 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()
【讨论】:
你能扩展一下 b 方法吗?如何实现MyCustomView
类和toggleFrontBackState()
方法?
似乎kolodaviewDatasource
只接受一个UIImageView
作为返回值,每当我尝试传递2 UIImageView
时,它就会变为空白
你应该返回 MyCustomView(不是两个 ImageView)。参见方法 B 中的代码
makeFront/BackView
方法是什么?
只需在这些函数中初始化一个 UIImageView。更新了上面的代码部分以上是关于如何将自定义视图动画化为自定义视图的主要内容,如果未能解决你的问题,请参考以下文章
如何将自定义 ListAdapter 设置为 appwidget 中的列表视图?