[SwiftUI/Swift]指定した時間だけ処理を遅らせる

目次

概要

とても単純だが、時たま処理を若干遅らせたいという時がある。
苦肉の策ではあるが、何かの処理をした後、画面のレイアウトや処理上の関係でほんの少しだけ遅らせたい時など。
そんなときはDispatchQueue.main.asyncAfterを使用する。

ソースコード

import SwiftUI

@main
struct TestApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            DelayProcessingView()
        }
    }
}

View表示

import SwiftUI

struct DelayProcessingView: View {
    @ObservedObject var viewModel: DelayProcessingViewModel = DelayProcessingViewModel()
    var body: some View {
        VStack {
            Spacer()
            if self.viewModel.isDisplayText {
                Text("ボタン押されてから時間が経ったよ")
            }
            Spacer()
            Button {
                self.viewModel.pushedButton()
            } label: {
                Text("3秒後に文字が表示されるボタン")
            }
            Spacer()
        }
    }
}

処理内容

import Foundation

class DelayProcessingViewModel: ObservableObject {
    @Published var isDisplayText = false
    
    func pushedButton() {
        let interval: TimeInterval = 3
        DispatchQueue.main.asyncAfter(deadline: .now() + interval, execute: {
            self.isDisplayText = true
        })
    }
}

デモ動画

詳細

他にも、Thread.sleep(forTimeInterval:)があるが、一般的にsleepメソッドはSwiftに限らず他の言語でも推奨はされていない。
流石に全ての処理を一時的に止めるというのは問題があると思われるので。

また、今回使用したDispatchQueue.mainはメインスレッドで処理を行うということでもある。
メインスレッドで行わなければならない処理は表示に関すること。
このDispatchQueue.mainは処理を遅らせる以外でも、APIから受け取ったデータを画面に反映させるときなどで使うと思う。

参考ページ:
iOS-Docs