通过这章,你将实现如下的相册效果:
在viewDidApear中添加卡片:
for image in images {
image.layer.anchorPoint.y = 0.0
image.frame = view.bounds
view.addSubview(image)
}
navigationItem.title = images.last?.title
在上一章中,我们只是在单个视图上调整transform属性,然后在3D空间中旋转它,现在由于我们的视图很多,所以我们只需设置它们父视图的透视图,节省大量工作。
var perspective = CATransform3DIdentity
perspective.m34 = -1.0/250.0
view.layer.sublayerTransform = perspective
在这里,可以使用layer的sublayerTransform属性来设置所有子layer的透视图。
设置图像的偏移量,在barButton的点击方法里添加:
@IBAction func toggleGallery(_ sender: AnyObject) {
var imageYOffset: CGFloat = 50.0
for subview in view.subviews {
guard let image = subview as? ImageViewCard else {
continue
}
var imageTransform = CATransform3DIdentity
imageTransform = CATransform3DTranslate(imageTransform, 0.0, imageYOffset, 0.0)
imageTransform = CATransform3DScale(imageTransform, 0.95, 0.6, 1.0)
imageTransform = CATransform3DRotate(imageTransform, .pi/8, -1.0, 0, 0)
image.layer.transform = imageTransform
imageYOffset += view.frame.height / CGFloat(images.count)
}
}
因为已经在父视图里面设置了透视属性,所以上面的方法里面只需要专注于transform,看起来效果是这样的:
当我们点击按钮切换到卡片状态时,还没有进入的动画,在设置image的transform之前,我们来添加动画效果:
let animation = CABasicAnimation(keyPath: "transform")
animation.fromValue = NSValue(caTransform3D: image.layer.transform)
animation.toValue = NSValue(caTransform3D: imageTransform)
animation.duration = 0.33
image.layer.add(animation, forKey: nil)
运行效果
当点击其中一个卡片时,将image切换到最前端,下面我们来实现这个功能。
其中有两个动画需要实现:一个是选择image的动画,另外一个是隐藏其它未选中的所有images。
func selectImage(selectedImage: ImageViewCard) {
for subview in view.subviews {
guard let image = subview as? ImageViewCard else {
continue
}
if image === selectedImage {//选中image
}else {//隐藏其它images:
UIView.animate(withDuration: 0.33, delay: 0.0, options: .curveEaseIn, animations: {
image.alpha = 0.0//首先设置为透明
}) { (_) in//动画完成后设置为不透明,因为所选image会置于最前端,所以看不到其它image,设置alpha为1.0没有影响
image.alpha = 1.0
image.layer.transform = CATransform3DIdentity
}
}
}
}
将所选image显示在最前端:
UIView.animate(withDuration: 0.33, delay: 0.0, options: .curveEaseIn, animations: {
image.layer.transform = CATransform3DIdentity
}) { (_) in
self.view.bringSubview(toFront: image)
}
最后设置标题
self.navigationItem.title = selectedImage.title
运行效果: