บทความนี้เน้นการใช้ CA Animations ใน iOS เพื่อสร้างแอนิเมชั่นที่ราบรื่น
ในช่วงเริ่มต้นการทำงานกับ iOS ฉันจะรู้สึกประหม่ามากเมื่อนักออกแบบเข้ามาหาฉันและขอแอนิเมชั่นในแอปที่พวกเขากำลังทำงานอยู่
ฉันเคยคิดว่าการออกแบบแอนิเมชั่นเป็นเรื่องง่าย แต่การนำไปใช้งานนั้นเป็นงานที่ยากมาก
ฉันจะได้รับความช่วยเหลือจาก 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 ฉันอ่านเกี่ยวกับเรื่องนี้และลองใช้ในโครงการตัวอย่าง ฉันประหลาดใจมาก มันทรงพลังและใช้งานง่ายมาก
ภาพเคลื่อนไหวหลักคืออะไร
แอนิเมชั่นหลักช่วยให้คุณรันแอนิเมชั่นหลายตัวโดยแทบไม่มีการใช้ 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
}
สำหรับการใช้งานนี้ ฉันใช้ 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
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
}
งานของฉันเสร็จแล้วที่นี่
โดยสรุป นี่คือข้อดีบางประการของการใช้ CA Animations:
- ใช้งานง่ายและใช้งานได้จริง
- ปรับแต่งได้มากมาย
- สามารถซิงค์ภาพเคลื่อนไหวหลายรายการได้
- ใช้งาน CPU เกือบเป็นศูนย์
นี่เป็นเพียงข้อดีบางประการ ความเป็นไปได้ไม่มีที่สิ้นสุด
ตอนนี้ เมื่อใดก็ตามที่มีข้อกำหนดสำหรับแอนิเมชั่น ฉันรู้สึกมั่นใจในการออกแบบและใช้งาน และฉันหวังว่าคุณจะรู้สึกเช่นเดียวกันหลังจากอ่านข้อความนี้
อย่าลังเลที่จะแสดงความคิดเห็นหรือข้อเสนอแนะใด ๆ