UIViewで遠近法変換を実行しようとしています(カバーフローで見られるような)
誰でもこれが可能かどうか知っていますか?
私はCALayer
を使用して調査し、すべての実用的なプログラマーCore Animationポッドキャストを実行しましたが、iPhoneでこの種の変換を作成する方法についてはまだ明確ではありません。
ヘルプ、ポインタ、またはコードスニペットの例は本当にありがたいです!
Benが言ったように、UIView's
を使用してCATransform3D
を使用して、layer's
rotation
を実行する必要があります。 ここで説明 のようにパースペクティブを機能させるコツは、CATransform3D
(m34)のマトリックスcells
の1つに直接アクセスすることです。マトリックス数学は私のものではなかったので、なぜこれが機能するのかを正確に説明することはできませんが、機能します。最初の変換ではこの値を負の分数に設定してから、レイヤー回転変換をそれに適用する必要があります。また、次のこともできるはずです。
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;
Swift 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
}
回転ごとに最初からレイヤー変換を再構築します。
この完全な例(コード付き)は here にあります。ここでは、Bill Dudneyの例に基づいて、いくつかのCALayers
にタッチベースの回転とスケーリングを実装しています。ページの一番下にあるプログラムの最新バージョンは、この種のパースペクティブ操作を実装しています。コードは、読みやすくする必要があります。
応答で参照するsublayerTransform
は、UIView's
CALayer
のサブレイヤーに適用される変換です。サブレイヤーがなくても心配する必要はありません。回転している1つのレイヤー内に2つのCALayers
が含まれているため、この例ではsublayerTransformを使用しています。
UIViewの変換プロパティに直接適用されるCore Graphics(Quartz、2Dのみ)変換のみを使用できます。 coverflowで効果を得るには、CATransform3Dを使用する必要があります。これは3D空間に適用されるため、目的のパースビューを提供できます。ビューではなくレイヤーにのみCATransform3Dを適用できるため、このためにレイヤーに切り替える必要があります。
Xcodeに付属の「CovertFlow」サンプルをご覧ください。これはMac専用です(つまり、iPhone用ではありません)が、多くの概念はうまく伝わります。
ICarousel SDKを使用して、正確なカルーセル効果を取得できます。
素晴らしい無料のiCarouselライブラリを使用して、iOSでインスタントカバーフローエフェクトを取得できます。 https://github.com/nicklockwood/iCarousel からダウンロードし、ブリッジングヘッダーを追加することでXcodeプロジェクトに簡単にドロップできます(Objective-Cで記述されています)。
Objective-CコードをSwiftプロジェクトに追加したことがない場合は、次の手順を実行します。
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
}