#14 自訂 controller 類別和利用 viewDidLoad 客製 App 畫面
2022彼得潘的 iOS App 程式設計入門
Published in
16 min readSep 16, 2022
功能需求
1 在 viewDidLoad 裡寫程式。
在 viewDidLoad 裡寫程式加入有興趣的功能。
這次想加入的功能有:
- 利用 CAGradientLayer 製作漸層
- 利用 SpriteKit Particle File 製造粒子效果
- 利用 UIView 的 mask製作圖片
- 利用 UIImageView 實現多張圖片連續播放以製作gif
- 利用AVFoundation SDK播放音樂
- 利用 CABasicAnimation & CAShapeLayer 繪製線條動畫
利用 CAGradientLayer 製作漸層
//漸層背景
func setupGradientBackground() {
//建立CAGradientLayer 物件
let gradientLayer = CAGradientLayer()
//讓漸層layer的大小等於 controller view 的大小。
gradientLayer.frame = view.bounds
//設定漸層的顏色
gradientLayer.colors = [
CGColor(srgbRed: 128/255,
green: 0/255,
blue: 128/255,
alpha: 1),
CGColor(srgbRed: 1,
green: 1,
blue: 1,
alpha: 1)
]
//將漸層的 layer 加在最底層。
view.layer.insertSublayer(gradientLayer, at: 0)
}
利用 SpriteKit Particle File 製造粒子效果
- 首先 先import SpriteKit
import SpriteKit
func snow() {
//建立SKView的物件
let skView = SKView(frame: view.frame)
//將skView加在最底層
view.insertSubview(skView, at: 0)
//將skView的背景設為clear
skView.backgroundColor = UIColor.clear
//建立一個SKScene來控制skView顯示
let scene = SKScene(size: skView.frame.size)
//利用anchorPoint控制scene出現的初始位置
scene.anchorPoint = CGPoint(x: 0.5, y: 1)
//將scene的背景設為clear
scene.backgroundColor = UIColor.clear
//選擇要呈現的效果
let emitterNode = SKEmitterNode(fileNamed: "Snow")
scene.addChild(emitterNode!)
//將presentScene顯示SKScene的內容
skView.presentScene(scene)
view.addSubview(skView)
}
利用 UIView 的 mask製作圖片
這次用badge作為mask
用sakura作為底圖
func mask() {
//產生badgeImageView跟sakuraImageView
let badgeImageView = UIImageView(image: UIImage(named: "badge"))
let sakuraImageView = UIImageView(image: UIImage(named: "sakura"))
//設定底圖的位置及大小
sakuraImageView.frame = CGRect(x: 50, y: 50, width: 300, height: 300)
//讓兩張圖片大小一樣
badgeImageView.frame = sakuraImageView.bounds
//設定mask為badge的圖片
sakuraImageView.mask = badgeImageView
view.addSubview(sakuraImageView)
}
利用 UIImageView 實現多張圖片連續播放以製作gif
1.先找一張自己想要的GIF
2.將GIF轉成多張圖片
3.透過上傳檔案到這個網站
4.選擇Download ZIP
5.將圖片加入Assets裡
6.設定image View來播放圖片
func gif() {
//先設定imageView的位置以及大小
let imageView = UIImageView(frame: CGRect(x: 90, y: 330, width: 222, height: 125))
//產生動畫圖便的UIImage的物件
let animatedImage = UIImage.animatedImageNamed("WhisperedOddIndianhare-size_restricted-", duration: 2.5)
//將animatedImage設定為imageView裡的image
imageView.image = animatedImage
view.addSubview(imageView)
}
利用AVFoundation SDK播放音樂
- 先import AVFoundation
import AVFoundation
2.
func music() {
if let url = URL(string: "https://video-ssl.itunes.apple.com/itunes-assets/Video125/v4/6f/42/62/6f426281-7a3b-0215-4c0b-16d7dd3d1e8d/mzvf_16827524069322136995.640x480.h264lc.U.p.m4v") {
let player = AVQueuePlayer()
let item = AVPlayerItem(url: url)
looper = AVPlayerLooper(player: player, templateItem: item)
player.play()
}
}
利用 CABasicAnimation & CAShapeLayer 繪製線條動畫
func firstWord() {
let path = UIBezierPath()
//letter N
path.move(to: CGPoint(x: 50, y: 500))
path.addQuadCurve(to: CGPoint(x: 50, y: 550), controlPoint: CGPoint(x: 48, y: 525))
path.move(to: CGPoint(x: 50, y: 500))
path.addQuadCurve(to: CGPoint(x: 75, y: 550), controlPoint: CGPoint(x: 65, y: 545))
path.move(to: CGPoint(x: 75, y: 550))
path.addQuadCurve(to: CGPoint(x: 75, y: 500), controlPoint: CGPoint(x: 70, y: 525))
//letter O
path.move(to: CGPoint(x: 110, y: 500))
path.addCurve(to: CGPoint(x: 110, y: 550), controlPoint1: CGPoint(x:80 , y: 500), controlPoint2: CGPoint(x: 80, y: 550))
path.move(to: CGPoint(x: 100, y: 495))
path.addCurve(to: CGPoint(x: 110, y: 550), controlPoint1: CGPoint(x: 140, y: 500), controlPoint2: CGPoint(x: 140, y: 550))
//letter G
path.move(to: CGPoint(x: 175, y: 500))
path.addCurve(to: CGPoint(x: 188, y: 525), controlPoint1:CGPoint(x: 135, y: 485), controlPoint2: CGPoint(x: 145, y: 600))
path.move(to: CGPoint(x: 190, y: 525))
path.addLine(to: CGPoint(x: 168, y: 527))
path.move(to: CGPoint(x: 188, y: 525))
path.addLine(to: CGPoint(x: 188, y: 550))
//letter I
path.move(to: CGPoint(x: 220, y: 500))
path.addQuadCurve(to: CGPoint(x: 220, y: 550), controlPoint: CGPoint(x: 218, y: 525))
path.move(to: CGPoint(x: 210, y: 500))
path.addLine(to: CGPoint(x: 230, y: 500))
path.move(to: CGPoint(x: 210, y: 550))
path.addLine(to: CGPoint(x: 230, y: 550))
//4
path.move(to: CGPoint(x: 210, y: 580))
path.addQuadCurve(to: CGPoint(x: 229, y: 633), controlPoint: CGPoint(x: 160, y: 650))
path.move(to: CGPoint(x: 220, y: 590))
path.addQuadCurve(to: CGPoint(x: 220, y: 650), controlPoint: CGPoint(x: 210, y: 620))
//6
path.move(to: CGPoint(x: 250, y: 580))
path.addQuadCurve(to: CGPoint(x: 260, y: 649), controlPoint: CGPoint(x: 220, y: 650))
path.move(to: CGPoint(x: 258, y: 650))
path.addQuadCurve(to: CGPoint(x: 230, y: 625), controlPoint: CGPoint(x: 280, y: 625))
let letterLayer = CAShapeLayer()
letterLayer.path = path.cgPath
letterLayer.strokeColor = UIColor.purple.cgColor
letterLayer.fillColor = UIColor.clear.cgColor
letterLayer.lineWidth = 5
view.layer.addSublayer(letterLayer)
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 3.5 //秒為單位
animation.repeatCount = .greatestFiniteMagnitude
letterLayer.add(animation, forKey: nil)
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
}func firstWord() {
let path = UIBezierPath()
//letter N
path.move(to: CGPoint(x: 50, y: 500))
path.addQuadCurve(to: CGPoint(x: 50, y: 550), controlPoint: CGPoint(x: 48, y: 525))
path.move(to: CGPoint(x: 50, y: 500))
path.addQuadCurve(to: CGPoint(x: 75, y: 550), controlPoint: CGPoint(x: 65, y: 545))
path.move(to: CGPoint(x: 75, y: 550))
path.addQuadCurve(to: CGPoint(x: 75, y: 500), controlPoint: CGPoint(x: 70, y: 525))
//letter O
path.move(to: CGPoint(x: 110, y: 500))
path.addCurve(to: CGPoint(x: 110, y: 550), controlPoint1: CGPoint(x:80 , y: 500), controlPoint2: CGPoint(x: 80, y: 550))
path.move(to: CGPoint(x: 100, y: 495))
path.addCurve(to: CGPoint(x: 110, y: 550), controlPoint1: CGPoint(x: 140, y: 500), controlPoint2: CGPoint(x: 140, y: 550))
//letter G
path.move(to: CGPoint(x: 175, y: 500))
path.addCurve(to: CGPoint(x: 188, y: 525), controlPoint1:CGPoint(x: 135, y: 485), controlPoint2: CGPoint(x: 145, y: 600))
path.move(to: CGPoint(x: 190, y: 525))
path.addLine(to: CGPoint(x: 168, y: 527))
path.move(to: CGPoint(x: 188, y: 525))
path.addLine(to: CGPoint(x: 188, y: 550))
//letter I
path.move(to: CGPoint(x: 220, y: 500))
path.addQuadCurve(to: CGPoint(x: 220, y: 550), controlPoint: CGPoint(x: 218, y: 525))
path.move(to: CGPoint(x: 210, y: 500))
path.addLine(to: CGPoint(x: 230, y: 500))
path.move(to: CGPoint(x: 210, y: 550))
path.addLine(to: CGPoint(x: 230, y: 550))
//4
path.move(to: CGPoint(x: 210, y: 580))
path.addQuadCurve(to: CGPoint(x: 229, y: 633), controlPoint: CGPoint(x: 160, y: 650))
path.move(to: CGPoint(x: 220, y: 590))
path.addQuadCurve(to: CGPoint(x: 220, y: 650), controlPoint: CGPoint(x: 210, y: 620))
//6
path.move(to: CGPoint(x: 250, y: 580))
path.addQuadCurve(to: CGPoint(x: 260, y: 649), controlPoint: CGPoint(x: 220, y: 650))
path.move(to: CGPoint(x: 258, y: 650))
path.addQuadCurve(to: CGPoint(x: 230, y: 625), controlPoint: CGPoint(x: 280, y: 625))
let letterLayer = CAShapeLayer()
letterLayer.path = path.cgPath
letterLayer.strokeColor = UIColor.purple.cgColor
letterLayer.fillColor = UIColor.clear.cgColor
letterLayer.lineWidth = 5
view.layer.addSublayer(letterLayer)
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 3.5 //秒為單位
animation.repeatCount = .greatestFiniteMagnitude
letterLayer.add(animation, forKey: nil)
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
}
成品展示: