Computer >> คอมพิวเตอร์ >  >> สมาร์ทโฟน >> iPhone

CAAnimation ช่วยให้ฉันเอาชนะความกลัวในการสร้างแอนิเมชั่นได้อย่างไร

บทความนี้เน้นการใช้ CA Animations ใน iOS เพื่อสร้างแอนิเมชั่นที่ราบรื่น

ในช่วงเริ่มต้นการทำงานกับ iOS ฉันจะรู้สึกประหม่ามากเมื่อนักออกแบบเข้ามาหาฉันและขอแอนิเมชั่นในแอปที่พวกเขากำลังทำงานอยู่

CAAnimation ช่วยให้ฉันเอาชนะความกลัวในการสร้างแอนิเมชั่นได้อย่างไร
บ้าไปแล้ว

ฉันเคยคิดว่าการออกแบบแอนิเมชั่นเป็นเรื่องง่าย แต่การนำไปใช้งานนั้นเป็นงานที่ยากมาก

ฉันจะได้รับความช่วยเหลือจาก Google, StackOverflow และเพื่อนร่วมงานของฉันในการนำไปใช้
ในระหว่างกระบวนการ ฉันเกิดความหวาดกลัวต่อแอนิเมชันและพยายามหลีกเลี่ยงอยู่เสมอ แต่นั่นก็เปลี่ยนไปในวันหนึ่ง

ค้นหา CAAnimation

ครั้งหนึ่ง ฉันต้องสร้างภาพเคลื่อนไหวตามลำดับภาพในมุมมองหนึ่ง แล้วก้าวแรกของฉันคืออะไร? แน่นอน StackOverflow!

ลิงค์แรกได้รับโค้ดแล้ว

let image_1 = UIImage(named: "image-1")!
let image_2 = UIImage(named: "image-2")!
let image_3 = UIImage(named: "image-3")!
let images = [image_1, image_2, image_3]
let animatedImage = UIImage.animatedImage(with: images, duration: 2.0)
imageView.image = animatedImage
CAAnimation ช่วยให้ฉันเอาชนะความกลัวในการสร้างแอนิเมชั่นได้อย่างไร

ดูเหมือนตรงไปตรงมาสวยใช่มั้ย? ถ้ามันง่ายขนาดนั้น ผมคงไม่เขียนบทความนี้หรอก

นี่คือแอนิเมชั่นที่ต้องการ:

CAAnimation ช่วยให้ฉันเอาชนะความกลัวในการสร้างแอนิเมชั่นได้อย่างไร
เป้าหมายสุดท้าย

และน่าจะชัดเจนแล้ว ฉันไม่ได้อยู่ใกล้มันเลย ฉันติดอยู่ ฉันควรจะปรับแต่งมากมายในแอนิเมชั่นนั้นและซิงค์มันทั้งหมดได้อย่างไร

จากนั้นเพื่อนร่วมงานบอกให้ฉันลองใช้ CAAnimation ฉันอ่านเกี่ยวกับเรื่องนี้และลองใช้ในโครงการตัวอย่าง ฉันประหลาดใจมาก มันทรงพลังและใช้งานง่ายมาก

ภาพเคลื่อนไหวหลักคืออะไร

แอนิเมชั่นหลักช่วยให้คุณรันแอนิเมชั่นหลายตัวโดยแทบไม่มีการใช้ CPU เลย
มันให้อัตราเฟรมสูงและการปรับแต่งมากมายที่คุณสามารถใช้กับโค้ดที่น้อยมาก

คุณสามารถดูรายละเอียดเพิ่มเติมในเอกสารได้ที่นี่:https://developer.apple.com/documentation/quartzcore

ฉันสามารถใช้งานพื้นฐานได้ภายในเวลาไม่กี่ชั่วโมง:

func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) {
        let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition)
        firstImageView.layer.add(basicAnimation1, forKey: "position")        
        let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition)
        secondImageView.layer.add(basicAnimation2, forKey: "position")
        self.addNextImage(forImageView: firstImageView)
    }
    func getBasicAnimation(withInitialPostion initialPos: CGPoint, finalPos: CGPoint) -> CABasicAnimation {
        let basicAnimation = CABasicAnimation(keyPath: "position")
        basicAnimation.fromValue = NSValue(cgPoint: initialPos)
        basicAnimation.toValue = NSValue(cgPoint: finalPos)
        basicAnimation.duration = 1
        basicAnimation.isRemovedOnCompletion = false
        basicAnimation.fillMode = CAMediaTimingFillMode.forwards
        basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
        return basicAnimation
    }
CAAnimation ช่วยให้ฉันเอาชนะความกลัวในการสร้างแอนิเมชั่นได้อย่างไร
ภาพเคลื่อนไหวพื้นฐานของ CA

สำหรับการใช้งานนี้ ฉันใช้ CABasicAnimation .

CABasicAnimation class ช่วยให้คุณสร้างภาพเคลื่อนไหวให้กับคุณสมบัติของเลเยอร์ (ซึ่งอาจเป็นสีพื้นหลัง ความทึบ ตำแหน่ง มาตราส่วน) ระหว่างสองค่า คุณเพียงแค่ต้องให้ค่าเริ่มต้นและสิ้นสุด แล้วส่วนที่เหลือจะได้รับการดูแล แอนิเมชั่นจะเริ่มทันทีในลูปการรันครั้งถัดไปตามที่อธิบายไว้อย่างครบถ้วนที่นี่

ตอนนี้ กลับไปที่ปัญหาของเรา

ในการดำเนินการนี้ ฉันใช้มุมมองภาพสองครั้งและเพิ่มรูปภาพแยกกันสองภาพ จากนั้นฉันก็สร้างแอนิเมชั่นพวกมันทีละตัวโดยใช้ CAAnimation

คุณสามารถค้นหาซอร์สโค้ดได้ที่นี่

หากคุณตรวจสอบ gif สุดท้าย คุณจะเห็นว่ามีบางอย่างผิดปกติ ก่อนที่ภาพแรกของกล่องของขวัญจะหายวับไป หูฟังจะกะพริบชั่วครู่แล้วภาพจะเลื่อนขึ้น

ทำไมสิ่งนี้จึงเกิดขึ้น

เป็นเพราะทันทีที่เราเพิ่มภาพเคลื่อนไหวลงในมุมมองภาพ เรากำลังเพิ่มภาพถัดไปในมุมมองนั้น (บรรทัดที่ 5 และ 6):

private func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) {
    let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition)
    firstImageView.layer.add(basicAnimation1, forKey: "position")    
    let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition)
    secondImageView.layer.add(basicAnimation2, forKey: "position")
    self.addNextImage(forImageView: firstImageView)
}

เรากำลังดิ้นรนกับปัญหาในการซิงค์รูปภาพทั้งสองในแอนิเมชัน แต่มีวิธีแก้ปัญหาเสมอกับ CAAnimation

ธุรกรรม CA

ธุรกรรมของ CA ช่วยให้เราซิงค์ภาพเคลื่อนไหวหลายรายการเข้าด้วยกัน ทำให้มั่นใจได้ว่าแอนิเมชั่นทั้งหมดที่เรารวมเข้าด้วยกันทั้งหมดเริ่มต้นพร้อมกัน

นอกจากนี้ คุณยังสามารถกำหนดบล็อกความสมบูรณ์ให้กับแอนิเมชั่นของคุณ ซึ่งจะถูกดำเนินการเมื่อแอนิเมชั่นทั้งหมดของคุณในชุดเดียวเสร็จสมบูรณ์

คุณสามารถอ่านเพิ่มเติมได้ที่นี่

private func addAnimation(firstImageView: UIImageView, secondImageView: UIImageView) {
    CATransaction.begin()
    CATransaction.setCompletionBlock {
        self.addNextImage(forImageView: firstImageView)
    }
    let basicAnimation1 = getBasicAnimation(withInitialPostion: centerPosition, finalPos: finalPosition)
    firstImageView.layer.add(basicAnimation1, forKey: "position")
    CATransaction.commit()
    
    let basicAnimation2 = self.getBasicAnimation(withInitialPostion: self.initalPosition, finalPos: self.centerPosition)
    secondImageView.layer.add(basicAnimation2, forKey: "position")
}

คุณเริ่มต้นด้วยการเขียน CATransaction.begin() . จากนั้นเขียนแอนิเมชั่นทั้งหมดที่คุณต้องการซิงค์ สุดท้ายโทร CATransaction.commit() ซึ่งจะเริ่มแอนิเมชั่นในบล็อก

มาดูกันว่าแอนิเมชั่นของเราจะเป็นอย่างไรตอนนี้:

CAAnimation ช่วยให้ฉันเอาชนะความกลัวในการสร้างแอนิเมชั่นได้อย่างไร
ธุรกรรม CA

สิ่งสุดท้ายที่ฉันต้องทำคือเพิ่มเอฟเฟกต์สปริงให้กับแอนิเมชั่น โชคดีที่ CAAnimation มีวิธีแก้ไขปัญหานี้เช่นกัน

แอนิเมชั่นสปริง CA

CA Spring Animation เมื่อเพิ่มลงในเลเยอร์ จะให้เอฟเฟกต์เหมือนสปริง ดูเหมือนว่าสปริงจะดึงเข้าหาเป้าหมาย

ยิ่งชั้นห่างจากเป้าหมายมากเท่าใด ความเร่งก็จะยิ่งมากขึ้นเท่านั้น

ช่วยให้สามารถควบคุมคุณลักษณะทางกายภาพได้ เช่น การหน่วงและความแข็งของสปริง – เอกสาร

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้จากเอกสารของ Apple:https://developer.apple.com/documentation/quartzcore/caspringanimation

มาปรับใช้กับโค้ดที่มีอยู่ของเรา:

private func getSpringAnimation(withInitialPostion initialPos: CGPoint, finalPos: CGPoint) -> CASpringAnimation {
    let basicAnimation = CASpringAnimation(keyPath: "position")
    basicAnimation.fromValue = NSValue(cgPoint: initialPos)
    basicAnimation.toValue = NSValue(cgPoint: finalPos)
    basicAnimation.duration = basicAnimation.settlingDuration
    basicAnimation.damping = 14
    basicAnimation.initialVelocity = 5
    basicAnimation.isRemovedOnCompletion = false
    basicAnimation.fillMode = CAMediaTimingFillMode.forwards
    return basicAnimation
}
CAAnimation ช่วยให้ฉันเอาชนะความกลัวในการสร้างแอนิเมชั่นได้อย่างไร
ว้าว

งานของฉันเสร็จแล้วที่นี่

โดยสรุป นี่คือข้อดีบางประการของการใช้ CA Animations:

  • ใช้งานง่ายและใช้งานได้จริง
  • ปรับแต่งได้มากมาย
  • สามารถซิงค์ภาพเคลื่อนไหวหลายรายการได้
  • ใช้งาน CPU เกือบเป็นศูนย์

นี่เป็นเพียงข้อดีบางประการ ความเป็นไปได้ไม่มีที่สิ้นสุด

ตอนนี้ เมื่อใดก็ตามที่มีข้อกำหนดสำหรับแอนิเมชั่น ฉันรู้สึกมั่นใจในการออกแบบและใช้งาน และฉันหวังว่าคุณจะรู้สึกเช่นเดียวกันหลังจากอ่านข้อความนี้
อย่าลังเลที่จะแสดงความคิดเห็นหรือข้อเสนอแนะใด ๆ