UIView에서 원근 변환을 수행하려고합니다 (예 : coverflow)
이것이 가능한지 아는 사람이 있습니까?
나는 CALayer
실용적인 프로그래머 인 Core Animation 팟 캐스트를 사용 하고 조사 했지만 iPhone에서 이런 종류의 변형을 만드는 방법에 대해서는 아직 명확하지 않습니다.
모든 도움, 포인터 또는 예제 코드 스 니펫은 정말 감사하겠습니다!
답변
Ben이 말했듯이 UIView's
a CATransform3D
를 사용하여 레이어를 사용 하여을 수행해야합니다 layer's
rotation
. 여기 에 설명 된 것처럼 원근법을 작동시키는 요령 cells
은 CATransform3D
(m34) 의 행렬 중 하나에 직접 액세스하는 것입니다 . 매트릭스 수학은 결코 내 일이 아니기 때문에 이것이 왜 효과가 있는지 정확히 설명 할 수는 없지만 그렇게합니다. 초기 변환의 경우이 값을 음의 분수로 설정 한 다음 레이어 회전 변환을 적용해야합니다. 또한 다음을 수행 할 수 있어야합니다.
목표 -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
}
각 회전마다 레이어 변형을 처음부터 다시 작성합니다.
Bill Dudney의 예제를 기반으로 터치 기반 회전 및 스케일링을 구현 한 코드의 전체 예제는 여기 에서 확인할 수 있습니다 CALayers
. 페이지 맨 아래에있는 최신 버전의 프로그램은 이러한 종류의 원근법 조작을 구현합니다. 코드는 읽기 편해야합니다.
sublayerTransform
당신이 당신의 응답을 참조는 당신의 서브 레이어에 적용되는 변환입니다 UIView's
CALayer
. 하위 계층이 없으면 걱정하지 마십시오. 예제에서 sublayerTransform을 사용하는 이유 CALayers
는 하나의 레이어 안에 두 개의 회전 이 있기 때문 입니다.
답변
UIView의 변형 속성에 직접 적용된 Core Graphics (Quartz, 2D 만) 변형 만 사용할 수 있습니다. Coverflow에서 효과를 얻으려면 3D 공간에 적용되는 CATransform3D를 사용해야하므로 원하는 투시도를 제공 할 수 있습니다. 뷰가 아닌 레이어에만 CATransform3D를 적용 할 수 있으므로이를 위해 레이어로 전환해야합니다.
Xcode와 함께 제공되는 “CovertFlow”샘플을 확인하십시오. 그것은 맥 전용 (즉, iPhone이 아닌)이지만 많은 개념이 잘 전달됩니다.
답변
Brad의 답변에 추가하고 구체적인 예를 제공하기 위해 비슷한 주제에 대한 다른 게시물의 내 답변 에서 빌려 왔습니다 . 내 대답에, 나는 간단한 스위프트를 생성 놀이터 당신이 할 수있는 다운로드 플레이 내가 층의 간단한 계층 구조와 UIView의 관점 효과를 만드는 방법을 보여줍니다, 그리고 내가 사용 사이의 서로 다른 결과를 보여줍니다 곳 transform
과 sublayerTransform
. 확인 해봐.
게시물의 일부 이미지는 다음과 같습니다.
답변
iCarousel SDK를 사용하여 정확한 캐 러셀 효과를 얻을 수 있습니다.
놀라운 무료 iCarousel 라이브러리를 사용하여 iOS에서 즉각적인 Cover Flow 효과를 얻을 수 있습니다. https://github.com/nicklockwood/iCarousel 에서 다운로드 하여 브리징 헤더 (Objective-C로 작성)를 추가하여 Xcode 프로젝트에 상당히 쉽게 드롭 할 수 있습니다.
Objective-C 코드를 Swift 프로젝트에 추가하지 않은 경우 다음 단계를 수행하십시오.
- iCarousel을 다운로드하고 압축을 풉니 다
- 압축을 푼 폴더로 이동하여 iCarousel 하위 폴더를 연 다음 iCarousel.h 및 iCarousel.m을 선택하고 프로젝트 탐색으로 드래그합니다. Xcode의 왼쪽 창입니다. Info.plist 바로 아래가 좋습니다.
- “필요한 경우 항목 복사”를 선택하고 완료를 클릭하십시오.
- Xcode는 “Objective-C 브리징 헤더를 구성 하시겠습니까?”라는 메시지를 표시합니다. “브리지 헤더 만들기”를 클릭하십시오. 프로젝트에 YourProjectName-Bridging-Header.h라는 새 파일이 나타납니다.
- 이 줄을 파일에 추가하십시오 : #import “iCarousel.h”
- 프로젝트에 iCarousel을 추가하면 사용할 수 있습니다.
- iCarouselDelegate 및 iCarouselDataSource 프로토콜을 모두 준수해야합니다.
스위프트 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
}