2010-12-27 30 views
10

Tôi muốn tạo ảnh động cho một đối tượng hình ảnh bằng cách di chuyển nó dọc theo một đường cong cụ thể. Nó không phải là một đường cong chung hoặc ngẫu nhiên mà là một đường cong theo một đường dẫn cụ thể trên màn hình.Di chuyển một đối tượng dọc theo đường cong trong phát triển iPhone

Hiện tại, Im tự xác định danh sách toạ độ x và y của đường dẫn mà tôi muốn đối tượng hình ảnh di chuyển bằng cách đặt khung của nó mỗi lần. Đây là một quá trình mất thời gian theo nghĩa là im đặt tọa độ x và y cụ thể của đường đi và di chuyển hình ảnh dọc theo nó. Có cách nào hiệu quả hơn để thực hiện việc này không?

Có cách nào mà tôi có thể chỉ định, giả sử, chỉ khoảng 15 - 20 điểm và có một đường cong được theo dõi dọc theo để di chuyển đối tượng không? Bất kỳ cách nào khác để đạt được điều này? Bất kì sự trợ giúp nào đều được đánh giá cao. Cảm ơn.

Trả lời

10

Bạn có thể sử dụng kết hợp UIBezierPath và CAKeyFrameAnimation. Tôi đã tìm thấy một bài đăng trên blog rất hữu ích đối phó với chủ đề này.

http://oleb.net/blog/2010/12/animating-drawing-of-cgpath-with-cashapelayer/

Dưới đây là một phiên bản đơn giản của những gì tôi được sử dụng (nó chỉ sinh động vẽ một hình vuông):

UIBezierPath *customPath = [UIBezierPath bezierPath]; 
[customPath moveToPoint:CGPointMake(100,100)]; 
[customPath addLineToPoint:CGPointMake(200,100)]; 
[customPath addLineToPoint:CGPointMake(200,200)]; 
[customPath addLineToPoint:CGPointMake(100,200)]; 
[customPath addLineToPoint:CGPointMake(100,100)]; 

UIImage *movingImage = [UIImage imageNamed:@"foo.png"]; 
CALayer *movingLayer = [CALayer layer]; 
movingLayer.contents = (id)movingImage.CGImage; 
movingLayer.anchorPoint = CGPointZero; 
movingLayer.frame = CGRectMake(0.0f, 0.0f, movingImage.size.width, movingImage.size.height); 
[self.view.layer addSublayer:movingLayer]; 

CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 
pathAnimation.duration = 4.0f; 
pathAnimation.path = customPath.CGPath; 
pathAnimation.calculationMode = kCAAnimationLinear; 
[movingLayer addAnimation:pathAnimation forKey:@"movingAnimation"]; 
+0

Cảm ơn. Điều đó đã giúp. Thay vì addLineToPoint, tôi sử dụng addQuadCurveToPoint và nó thực hiện công việc. Một câu hỏi khác ở đây. Làm thế nào để phát hiện sự kết thúc của một CAKeyFrameAnimation? Có phương thức đại biểu nào cho điều này không? Đại diện animationDidStop không được gọi khi hoạt ảnh dừng lại. – Nathan

+0

Xin lỗi. Đã khắc phục điều đó. Lỗi lầm ngớ ngẩn. Tôi đã sử dụng các đại diện animationDidStop của một UIView thay vì một cho một CAAnimation. Bây giờ đại biểu cũng làm việc. – Nathan

0

Trong Swift-3 phiên bản của @Jilouc: -

override func viewDidLoad() { 
     super.viewDidLoad() 
     addAdditiveAnimation() 
     initiateAnimation() 
    } 

    //curve which follows a particular path 
    func pathToTrace() -> UIBezierPath { 
      let path = UIBezierPath(ovalIn: CGRect(x: 120 , y: 120, width: 100, height: 100)) 
      let shapeLayer = CAShapeLayer() 
      shapeLayer.path = path.cgPath 
      shapeLayer.strokeColor = UIColor.red.cgColor 
      shapeLayer.lineWidth = 1.0 
      self.view.layer.addSublayer(shapeLayer) 
      return path 
     } 

func addAdditiveAnimation() { 
     let movement = CAKeyframeAnimation(keyPath: "position") 
     movement.path = pathToTrace().cgPath 
     movement.duration = 5 
     movement.repeatCount = HUGE 
     movement.calculationMode = kCAAnimationPaced 
     movement.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)] 
     self.movement = movement 
} 

func createLayer() -> CALayer { 
     let layer = CALayer() 
     let image = UIImage(named: "launch.png") 
     layer.frame = CGRect(x: 0 , y: 0, width: (image?.size.width),height: (image?.size.height)) 
     layer.position = CGPoint(x: 5, y: 5) 
     layer.contents = image?.cgImage 
     layer.anchorPoint = .zero 
     layer.backgroundColor = UIColor.red.cgColor 
     //layer.cornerRadius = 5 
     self.view.layer.addSublayer(layer) 
     return layer 
    } 

func initiateAnimation() { 
     let layer = createLayer() 
     layer.add(self.movement, forKey: "Object Movement") 
    } 

Github Demo

Các vấn đề liên quan