ルパン三世風タイトルコールをSwiftUIで作る方法
Kotlinを調べるのにQiitaを見ていたら"【Android】ルパン三世風タイトルコールをなるべく簡単に作る"を発見しました。
この記事では、ViewModelを使った簡単なサンプルコードになっていて、SwiftUIにしたら参考になるのではないかと思いました。
今回作成するアプリの完成イメージ
文字を入力するテキストフィールドとStartボタンを配置し、Startボタンを押すとタイトルコールが表示されるアプリです。
ViewModelを作成する
今回は、ファイル名をLupinTitleViewModel.swiftとしました。
入力した文字を格納するための変数titleを用意し、startTitleCall()を呼び出すとタイトルコール中かどうか判定するフラグisTypingをtrueに書き換えます。その後タイトルコール中に表示すべき変数typeWriteに文字列を逐次格納するようにしています。
音源は、"【Android】ルパン三世風タイトルコールをなるべく簡単に作る"と同じ魔王魂の銃03と点火04を利用しています。
import Foundation
import UIKit
import AVFoundation
class LupinTitleViewModel: NSObject, ObservableObject {
@Published var title:String = ""
@Published var typeWrite:String = ""
@Published var isTyping:Bool = false
//音楽:魔王魂 - 銃03
private let titleSound = try! AVAudioPlayer(data: NSDataAsset(name: "se_maoudamashii_battle_gun03")!.data)
//音楽:魔王魂 - 点火04
private let typewriter = try! AVAudioPlayer(data: NSDataAsset(name: "se_maoudamashii_se_ignition04")!.data)
func startTitleCall() {
if title.count == 0 {
return
}
titleSound.prepareToPlay()
typewriter.prepareToPlay()
DispatchQueue.global().async {
DispatchQueue.main.sync {
self.isTyping = true
}
for string in self.title {
Thread.sleep(forTimeInterval: 0.15)
self.titleSound.stop()
self.titleSound.currentTime = 0.0
self.titleSound.play()
DispatchQueue.main.sync {
self.typeWrite = String(string)
}
}
Thread.sleep(forTimeInterval: 0.15)
self.titleSound.stop()
self.typewriter.play()
DispatchQueue.main.sync {
self.typeWrite = self.title
}
Thread.sleep(forTimeInterval: 2)
DispatchQueue.main.sync {
self.isTyping = false
self.typeWrite = ""
}
}
}
}
ContentViewを作成する
今回は、タイトルコール中かどうかを判定して、デザインを変更するようにしています。本来は、TitileCallViewなど作るべきなのでしょうが今回は簡単なデザインなのでベタ書きします。
import SwiftUI
struct ContentView: View {
@ObservedObject private var lupinTitleViewModel = LupinTitleViewModel()
var body: some View {
Group {
if lupinTitleViewModel.isTyping {
ZStack {
Color(.black)
.edgesIgnoringSafeArea(.all)
VStack {
Spacer()
Text(lupinTitleViewModel.typeWrite)
.font(.largeTitle)
.fontWeight(.heavy)
.foregroundColor(.white)
Spacer()
Text("音楽:魔王魂")
.foregroundColor(.white)
}
}
} else {
VStack {
TextField("Title", text: $lupinTitleViewModel.title)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
Button(action: {
self.lupinTitleViewModel.startTitleCall()
}) {
Text("Start")
.padding()
}
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
これで終わりです。
最後に
SwiftUIを利用すると、画面デザインと処理する部分を分けるようにしなくてはならなくなります。従来のViewControllerにベタガキするようなことはできないので、整理できていいのかも知れません。
作成したサンプルコードはこちらのGithubに公開しています。
ありがとうございました。
この記事が気に入ったらサポートをしてみませんか?