48444


labelの文字を5秒後に変更したい（例、labelの文字が「あいうえお」だったら、５秒後に「かきくけこ」に変わる）方法を探しているのですが、見つかりません。  
TextFieldの文字をLabelに表示したりするのは分かるのですが。  
ご教授頂けると幸いです。  
宜しくお願いします。

Swift4


CC BY-SA 4.0
2018-09-15T13:27:47.107
48431
2018-09-16T03:22:32.867
23704
question
swift ios xcode swift4
labelの文字を5秒後に変更したい


まずは前提ですが、この程度のプロジェクトは「コードの意味がわかるし、自分でXcodeのテンプレから作成することができる」と言うことでよろしいでしょうか。

[![画像の説明をここに入力](https://i.stack.imgur.com/lylNR.png)](https://i.stack.imgur.com/lylNR.png)

ViewController.swift

[code]

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var textLabel: UILabel!
    
        @IBOutlet weak var textField: UITextField!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            textLabel.text = "あいうえお"
        }
    
        @IBAction func buttonPressed(_ sender: Any) {
            textLabel.text = textField.text
        }
    
    }
    
[/code]

※画像の挿入もコード整形も、質問を編集する時にも使える機能です。このように単純な例では画像なんてなくても大体想像がつくでしょうが、言葉を重ねるより1枚の画像を示した方がわかりやすそうな場合には、臆せずにその機能を利用して下さい。「投稿」や「保存」のボタンを押すまでは、プレビューエリアを見ながらあれこれ試して見られると良いと思います。

* * *

## `Timer`を使う方法

「5秒後に」何かを行う、と言った場合に一番よく使われる方法です。Objective-Cだけの時代からあるクラス(Objective-
Cでの名前は`NSTimer`)ですが、近年Swiftから使いやすいメソッドも追加され、いまでも多用されています。

上記の`buttonPressed(_:)`メソッドを以下のように書き換えてみて下さい。

[code]

    @IBAction func buttonPressed(_ sender: Any) {
        Timer.scheduledTimer(withTimeInterval: 5, repeats: false) {_ in
            self.textLabel.text = self.textField.text
        }
    }
    
[/code]

呼んでいるのは[`scheduledTimer(withTimeInterval:repeats:block:)`というメソッド](https://developer.apple.com/documentation/foundation/timer/2091889-scheduledtimer)なのですが、最後の`block:`に与える引数は[SwiftのTrailing
Closureの書き方](https://docs.swift.org/swift-
book/LanguageGuide/Closures.html#ID102)をしているので、`)`の後ろで`block:`というラベルもなくなっています。

ちなみに最初の引数は`TimeInterval`型で、これは実は単に`Double`の別名なんですが、Appleのframeworkで`TimeInterval`型が使われている場合、単位は必ず「秒」になります。

実際にプロジェクトを作って動きを確かめて下さい。

* * *

## libdispatch(GCD)を使う方法

(私ら年寄りの感覚からすると)比較的最近使われるようになった方法です。libdispatchを使いこなしている方は、こちらの方がお好きな方が多いように思います。

[code]

    @IBAction func buttonPressed(_ sender: Any) {
        DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
            self.textLabel.text = self.textField.text
        }
    }
    
[/code]

使っているのは、`DispatchQueue`クラスの[`asyncAfter(deadline:qos:flags:execute:)`メソッド](https://developer.apple.com/documentation/dispatch/dispatchqueue/2300100-asyncafter)なのですが、中2つの`qos:`と`flags:`はデフォルト通りでいい場合は省略可(と言うかこんな単純な例では普通は省略します)、最後の`execute:`は、またTrailing
Closureの構文を使用しています。

`.now() + 5`と言うのは`DispatchTime`型の引数を書くときに独特のものですが、`DispatchTime.now() +
5`をドット記法を使って型名の部分を省略したものです。「今+5」が「今から5秒後」を表しているので、慣れれば意味はわかりやすいですね。

* * *

注意点としては、上に挙げたような方法では時間の精度は100msec、つまりせいぜい0.1秒程度です。1フレーム単位の精度で画面を更新したい、なんて言う場合にはアニメーションやゲームに使われているテクニックが必要になり、難度がはるかに上がります。

「5秒後」なんてキーワードにネットで検索してみると、意外に良記事は見つかりませんでした。この回答を少しでも参考にしていただければ幸いです。


CC BY-SA 4.0
2018-09-16T03:22:32.867
48444
2018-09-16T03:22:32.867
13972
48431
answer