6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Swift】TextField全選択時の処理で「2回に1度しか全選択の状態にならない」場合の対処方法

Last updated at Posted at 2018-05-05

はじめに

前回掲載した 【Swift】 TextFieldをタップした時に全選択できるようにする において、
不具合を見つけたため、今回はその対処方法を載せます。

事象

2回に1度しか全選択の状態にならない

1回目にTextFieldをタップした時は全選択ができているが、再度繰り返し同じ動作をすると全選択とならない。

再現

  1. シュミレータ起動後、対象のTextFieldを選択(タップ)する。
  2. キーボードが上がり、TextFieldが全選択される。
  3. 確認後、TextField以外の部分を選択し、TextFieldの選択状態を解除する(キーボードが下がった状態)。
  4. 再度、対象のTextFieldを選択(タップ)する。
  5. TextField上で全選択がされず、通常の選択状態となる or 選択動作が上手くされない

原因

原因のコード

1. TextFieldの選択範囲を指定する方法

ViewController.swift
func textFieldDidBeginEditing(_ textField: UITextField) {

    // TextFieldの選択範囲を指定する
    textField.selectedTextRange = textField.textRange(
        from: textField.beginningOfDocument,
        to: textField.endOfDocument)
}

2. TextField内の文字列を選択状態にする方法

ViewController.swift
func textFieldDidBeginEditing(_ textField: UITextField) {

    // nilチェック
    if textField != self.urlTextField {
        return
    }

    // TextField内の文字列を選択状態にする
    textField.selectAll(self.textField.text)
}

対処方法

調べてみたら、以下の同事象と似ている記事を見つけました。

stackoverflowより

これによると、
遅延処理を加えると解消されるとあったので、実際に試してみる

遅延処理について

遅延処理を加える実装方法(以下3つ)とその参考記事を簡単にまとめてみました。

色々記事を見た結果、
今回はSwift3以降で使用可能となったdispatch_afterを適用させてみようと思います。

遅延処理dispatch_afterの適用

1.の「TextFieldの選択範囲を指定する方法」に適用する

ViewController.swift
func textFieldDidBeginEditing(_ textField: UITextField) {

    // 遅延処理 → 0.1秒後に実行
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        // TextFieldの選択範囲を指定する
        textField.selectedTextRange = textField.textRange(
            from: textField.beginningOfDocument,
            to: textField.endOfDocument)
    }
}

2.の「TextField内の文字列を選択状態にする方法」に適用する

ViewController.swift
func textFieldDidBeginEditing(_ textField: UITextField) {

    // nilチェック
    if textField != self.urlTextField {
        return
    }
    
    // 遅延処理 → 0.1秒後に実行
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        // TextField内の文字列を選択状態にする
        textField.selectAll(self.textField.text)
    }
}

修正後、「2回に1度しか全選択の状態にならない」が解消され、
TextField選択時に全選択されるようになった。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?