我正在寻找对 UIView 执行透视变换(例如在coverflow中看到的)
有谁知道这是否可能?
我已经使用CALayer
并浏览了所有实用程序员 Core Animation 播客,但我仍然不清楚如何在 iPhone 上创建这种转换。
任何帮助、指针或示例代码片段将不胜感激!
我正在寻找对 UIView 执行透视变换(例如在coverflow中看到的)
有谁知道这是否可能?
我已经使用CALayer
并浏览了所有实用程序员 Core Animation 播客,但我仍然不清楚如何在 iPhone 上创建这种转换。
任何帮助、指针或示例代码片段将不胜感激!
正如 Ben 所说,您需要使用UIView's
图层,使用 aCATransform3D
来执行layer's
rotation
. 如此处所述,获得透视工作的技巧是直接访问(m34)的矩阵cells
之一。CATransform3D
矩阵数学从来都不是我的事,所以我无法确切解释为什么会这样,但确实如此。您需要将此值设置为初始变换的负分数,然后将图层旋转变换应用于该值。您还应该能够执行以下操作:
Objective-C
UIView *myView = [[self subviews] objectAtIndex:0];
CALayer *layer = myView.layer;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -500;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 45.0f * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
斯威夫特 5.0
if let myView = self.subviews.first {
let layer = myView.layer
var rotationAndPerspectiveTransform = CATransform3DIdentity
rotationAndPerspectiveTransform.m34 = 1.0 / -500
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 45.0 * .pi / 180.0, 0.0, 1.0, 0.0)
layer.transform = rotationAndPerspectiveTransform
}
它为每次旋转从头开始重建图层变换。
可以在此处CALayers
找到一个完整的示例(带有代码) ,根据 Bill Dudney 的示例,我在其中实现了基于触摸的旋转和缩放。最新版本的程序,在页面的最底部,实现了这种透视操作。代码应该相当简单易读。
您在回复中引用的sublayerTransform
是应用于您的子层的转换UIView's
CALayer
。如果您没有任何子图层,请不要担心。我在示例中使用 sublayerTransform 只是因为CALayers
我正在旋转的一层中包含两个。
您只能使用直接应用于 UIView 的变换属性的核心图形(Quartz,仅限 2D)变换。要在 Coverflow 中获得效果,您必须使用 CATransform3D,它应用于 3-D 空间,因此可以为您提供所需的透视图。您只能将 CATransform3D 应用于图层,而不是视图,因此您将不得不为此切换到图层。
查看 Xcode 附带的“CovertFlow”示例。它仅适用于 mac(即不适用于 iPhone),但很多概念都可以很好地转移。
斯威夫特 5.0
func makeTransform(horizontalDegree: CGFloat, verticalDegree: CGFloat, maxVertical: CGFloat,rotateDegree: CGFloat, maxHorizontal: CGFloat) -> CATransform3D {
var transform = CATransform3DIdentity
transform.m34 = 1 / -500
let xAnchor = (horizontalDegree / (2 * maxHorizontal)) + 0.5
let yAnchor = (verticalDegree / (-2 * maxVertical)) + 0.5
let anchor = CGPoint(x: xAnchor, y: yAnchor)
setAnchorPoint(anchorPoint: anchor, forView: self.imgView)
let hDegree = (CGFloat(horizontalDegree) * .pi) / 180
let vDegree = (CGFloat(verticalDegree) * .pi) / 180
let rDegree = (CGFloat(rotateDegree) * .pi) / 180
transform = CATransform3DRotate(transform, vDegree , 1, 0, 0)
transform = CATransform3DRotate(transform, hDegree , 0, 1, 0)
transform = CATransform3DRotate(transform, rDegree , 0, 0, 1)
return transform
}
func setAnchorPoint(anchorPoint: CGPoint, forView view: UIView) {
var newPoint = CGPoint(x: view.bounds.size.width * anchorPoint.x, y: view.bounds.size.height * anchorPoint.y)
var oldPoint = CGPoint(x: view.bounds.size.width * view.layer.anchorPoint.x, y: view.bounds.size.height * view.layer.anchorPoint.y)
newPoint = newPoint.applying(view.transform)
oldPoint = oldPoint.applying(view.transform)
var position = view.layer.position
position.x -= oldPoint.x
position.x += newPoint.x
position.y -= oldPoint.y
position.y += newPoint.y
print("Anchor: \(anchorPoint)")
view.layer.position = position
view.layer.anchorPoint = anchorPoint
}
您只需要使用您的学位调用该函数。例如:
var transform = makeTransform(horizontalDegree: 20.0 , verticalDegree: 25.0, maxVertical: 25, rotateDegree: 20, maxHorizontal: 25)
imgView.layer.transform = transform
您可以使用 iCarousel SDK 获得准确的轮播效果。
通过使用奇妙且免费的 iCarousel 库,您可以在 iOS 上获得即时的 Cover Flow 效果。您可以从https://github.com/nicklockwood/iCarousel下载它,并通过添加一个桥接头(它是用 Objective-C 编写的)相当容易地将它放入您的 Xcode 项目中。
如果您之前没有将 Objective-C 代码添加到 Swift 项目中,请按照以下步骤操作:
斯威夫特 3 示例代码:
override func viewDidLoad() {
super.viewDidLoad()
let carousel = iCarousel(frame: CGRect(x: 0, y: 0, width: 300, height: 200))
carousel.dataSource = self
carousel.type = .coverFlow
view.addSubview(carousel)
}
func numberOfItems(in carousel: iCarousel) -> Int {
return 10
}
func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView {
let imageView: UIImageView
if view != nil {
imageView = view as! UIImageView
} else {
imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 128, height: 128))
}
imageView.image = UIImage(named: "example")
return imageView
}