본문 바로가기
iOS/설명

[iOS] CALayer의 anchorPoint, position

by Sky Titan 2021. 12. 8.
728x90
 

[CoreAnimation]CALayer의 AnchorPoint, zPosition

AnchorPoint UIView에서 frame, bounds, center 속성은 CALayer에서도 동일하게 frame, bounds, position 속성으로 가지고 있습니다. frame은 외부에서 바라보는 좌표를 나타내고 bounds는 내부에서 바라보는 좌표를 나

minsone.github.io

 

 

Apple Developer Documentation

 

developer.apple.com

anchorPoint

  • 해석 그대로 해당 layer의 축이 될 곳을 가리키는 좌표 값이다
  • x, y 좌표 모두 0~1까지의 값을 기준으로 (0, 0)이 좌측 상단, (1, 1)이 우측 하단을 가리킨다.
    • default는 (0.5, 0.5) 이다. (정중앙)
  • layer.position은 부모뷰에서 해당 layer의 anchorPoint를 위치시킬 곳을 의미한다.
  • anchorPoint를 지정후에 layer의 position값을 지정하면 해당 anchorPoint를 position좌표에 위치 시킨다.
  • CALayer에 회전 애니메이션 적용시 상당히 중요하게 사용된다.
  • 주의: layer.frame을 지정해주어야 동작한다!!

 

예제

  1. 원형의 View를 만든다.
  2. View 정중앙을 알려주는 파란색 점을 추가한다.
  3. anchorPoint실습을 도와줄 빨간색 사각형 bar를 추가한다.
  4. layer.position은 View의 정중앙으로 한다.
  5. 버튼을 클릭해가며 anchorPoint를 바꿔본다.

 

AnchorPointPracticeView.swift

//
//  AnchorPointPracticeView.swift
//  Practice
//
//  Created by 박준현 on 2021/12/08.
//

import UIKit

class AnchorPointPracticeView: UIView {
    
    var rectLayer: CAShapeLayer?
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        
        layer.borderWidth = 1
        layer.borderColor = UIColor.black.cgColor
        layer.cornerRadius = frame.width / 2
    }
  
    override func didMoveToSuperview() {
        super.didMoveToSuperview()
        addRectLayer()
        addCenterDot()
    }
    
    func addRectLayer() {
        let path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: frame.width / 2, height: 10))
        path.close()
        let rectLayer = CAShapeLayer()
        rectLayer.frame = path.bounds // 중요: frame을 지정해주어야 anchorPoint가 동작한다.
        rectLayer.fillColor = UIColor.red.cgColor
        rectLayer.anchorPoint = CGPoint(x: 0, y: 0) // layer 좌측상단 지점으로 초기화
        rectLayer.position = CGPoint(x: frame.width / 2, y: frame.height / 2) // anchorPoint가 위치할 곳 (부모뷰 기준 좌표 -> 현재는 부모뷰의 정중앙에 위치하겠다는 뜻)
        rectLayer.path = path.cgPath
        
        rectLayer.setNeedsDisplay()
        self.layer.addSublayer(rectLayer)
        self.rectLayer = rectLayer
    }
    
    //수동으로 anchorPoint 지정
    func setRectLayerAnchorPoint(point: CGPoint) {
        rectLayer?.anchorPoint = point
    }
    
    //중앙 표시 점 layer 추가
    func addCenterDot() {
        let dotLayer = CAShapeLayer()
        dotLayer.path = UIBezierPath(arcCenter: CGPoint(x: frame.width / 2, y: frame.height / 2), radius: 5, startAngle: 0, endAngle: 2 * .pi, clockwise: true).cgPath
        dotLayer.fillColor = UIColor.blue.cgColor
        dotLayer.setNeedsDisplay()
        self.layer.addSublayer(dotLayer)
    }
    
    func rotate() {
        let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
        rotateAnimation.fromValue = 0
        rotateAnimation.toValue = 2 * CGFloat.pi
        rotateAnimation.duration = 0.5
        rotateAnimation.isRemovedOnCompletion = true
        
        self.rectLayer?.add(rotateAnimation, forKey: "rotate")
    }
}

 

ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var anchorPointView: AnchorPointPracticeView!
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }

    //anchorPoint기준으로 360도회전
    @IBAction func rotate(_ sender: Any) {
        anchorPointView.rotate()
    }
    
    //좌측 상단
    @IBAction func leftTop(_ sender: Any) {
        anchorPointView.setRectLayerAnchorPoint(point: CGPoint(x: 0, y: 0))
    }
    
    //좌측 하단
    @IBAction func leftBottom(_ sender: Any) {
        anchorPointView.setRectLayerAnchorPoint(point: CGPoint(x: 0, y: 1))
    }
    
    //정중앙
    @IBAction func center(_ sender: Any) {
        anchorPointView.setRectLayerAnchorPoint(point: CGPoint(x: 0.5, y: 0.5))
    }
    
    //우측 상단
    @IBAction func rightTop(_ sender: Any) {
        anchorPointView.setRectLayerAnchorPoint(point: CGPoint(x: 1, y: 0))
    }
    
    //우측 하단
    @IBAction func rightBottom(_ sender: Any) {
        anchorPointView.setRectLayerAnchorPoint(point: CGPoint(x: 1, y: 1))
    }
}

 

728x90

댓글