うまく表現できませんが、チュートリアルなんかでよく、「カタカタカタカタ」と少しずつテキストが表示されていくシーンがあるじゃないですか!(伝わってください)
今回はそれを実装しました。
既存のライブラリで存在していたら教えてください
少しずつテキストを表示して、表示中にタップされたらテキストを全部まとめて表示するUILabelを実装しました。
// テキストを表示中を表すフラグと、早く表示するためのフラグです
fileprivate var isPlaying = true
fileprivate var isFast = false
fileprivate var tutorialLbl: UILable!
override func viewDidLoad() {
super.viewDidLoad()
// タップを検知
self.singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(self.singleTap(_:)))
self.view.addGestureRecognizer(self.singleTapGesture)
}
// 画面をタップした際に発火する関数
@objc func singleTap(_ sender: UITapGestureRecognizer){
// 一度タップされていてテキストがカタカタと表示中のとき、表示速度を早めるフラグを立てる
if self.isPlaying {
self.isFast = true
return
}
self.isPlaying = true
// このメソッドはよしなに
showTutorial()
}
fileprivate func showTutorial() {
// ラベルをテキトーに作成
self.tutorialLbl = UILabel()
self.tutorialLbl.frame = CGRect(x: 0, y: self.view.bounds.maxY - 200, width: self.view.bounds.width, height: 200)
self.view.addSubview(self.tutorialLbl)
let text = "アイウエオかきくけこさしすせそ"
// ここで表示
self.showTextDynamically(label: self.tutorialLbl, text: Array(text), idx: 0)
}
fileprivate func showTextDynamically(label: UILabel, text: [Character], idx: Int) {
var waitTime = 0.0
// 表示速度を早めるフラグが立っていないとき、0.1秒間に一文字表示するよう待ち時間を設定
if !self.isFast {
waitTime = 0.1
}
// テキストを表示しきったときリターン
if text.count == idx {
self.isPlaying = false
self.isFast = false
return
}
if label.text == nil {
label.text = ""
}
// 0.1秒遅延して再帰する
DispatchQueue.main.asyncAfter(deadline: .now() + waitTime) {
// テキストをlabelに追加する
let c = text[idx]
label.text! += String(c)
self.showTextDynamically(label: label, text: text, idx: idx + 1)
}
}
こういうのってtimerを使うのが一般的なんでしょうか。