20200628のSwiftに関する記事は4件です。

スクショ・画面録画されたことを通知する方法

スクリーンショットや画面録画がされたことを通知するには,そのViewControllerの中で

override func viewWillAppear(_ animated: Bool) {

        NotificationCenter.default.addObserver(self, 
        selector: #selector(didTakeScreenshot), name:                                UIApplication.userDidTakeScreenshotNotification, object: nil)

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(didCapturedScreen),
            name: UIScreen.capturedDidChangeNotification,
            object: nil
        )

    }

ViewDidLoad()でも構いません。
didTakeScreenshotdidCapturedScreen自分で決める関数であるので、例えば以下のようにします。

@objc func didTakeScreenshot() {
    print("スクリーンショット")
 }

必要に応じて通知を削除します。

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillAppear(animated)
        NotificationCenter.default.removeObserver(self,name: UIApplication.userDidTakeScreenshotNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIScreen.capturedDidChangeNotification, object: nil)
    }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

NotificationCenter.default.removeObserverの大切さを痛感した話

起きたこと

IMG_0347 2.PNG IMG_0343.PNG
TableViewControllerとNavigationControllerでできているチャットアプリを作成していたところ、トーク画面でスクショすると自動送信されるメッセージが他のトーク画面でスクショしても送信されるバグが発見された。
IMG_0331 2.PNG

原因と処理

スクショの監視するObserVerをViewDidLoad()の中に書いていたのですが、

NotificationCenter.default.addObserver(self, selector: #selector(didTakeScreenshot), name: UIApplication.userDidTakeScreenshotNotification, object: nil)

NavigationController画面遷移をしたときに通知を外していないことが原因でした。

NotificationCenter.default.removeObserver(self,name: UIApplication.userDidTakeScreenshotNotification, object: nil)

viewWillDisappearの中で書くことで期待した処理をすることが出来ました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

複数のTextFieldにそれぞれ文字数の制限をつける

できること

  • TextFieldの文字数を取得する
  • 複数のTextFieldにそれぞれ異なる条件(①, ②)をつける
  • ①,②を満たす時のみボタンを活性にする

ex) TextFieldアには四文字以上、TextFieldイは5文字以上10文字未満の時のみログインボタンが押せるようにする

TextFieldの文字数を取得する

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        let textLength = (textField.text! as NSString).replacingCharacters(in: range, with:                  string).count

        print("テキストが入力された\(textLength)")//文字数を表示
        return true
}

TextFieldに文字が入力されるたびに呼び出されます。

複数のTextFieldを扱う

複数のTextFieldを扱いたい時には、TextFieldにtagを設定します。
スクリーンショット 2020-06-28 14.03.45.jpg

tagを設定することで、上述したfunc textField()の中でTextFieldを一意に定めることができます。

//さっきの続き
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        let textLength = (textField.text! as NSString).replacingCharacters(in: range, with:            string).count

switch textField.tag {
        case 0:
           print("TextFieldアが押された\(textLength)")
        case 1:
           print("TextFieldイが押された\(textLength)")
          default:
            break
        }

}

TextFieldにそれぞれ異なる条件をつける

TextFieldアには四文字以上、TextFieldイは5文字以上10文字未満の時のみログインボタン(loginButton)が押せるようにするという実装をすることにします。

この時、二つの条件がそれぞれ真である時のみボタンの活性を決めるisEnabledが真でなければなりません。この時点で真理値が複雑に絡んでいることがわかるので、関数を作ることを試みます。

private func checkButton() {
        if TextFieldABool && TextFieldBBool {
            loginButton.isEnabled = true
            loginButton.setTitleColor(UIColor.black, for: .normal)

        } else {
            loginButton.isEnabled = false
            loginButton.setTitleColor(UIColor.gray, for: .normal)

        }
    }//二つの真理値がともに真である時のみボタンを活性にして色を白、そうでない時ボタンを非活性にして色を灰色にする。

この関数が呼ばれるたび、二つの真理値の状態に基づいた処理が行われます。

//さっきの続き
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        let textLength = (textField.text! as NSString).replacingCharacters(in: range, with:            string).count

switch textField.tag {
        case 0:
           print("TextFieldアが押された\(textLength)")

           if textLength >= 4 {
             TextFieldABool = true
          } else {
             TextFieldABool = false
          }
        case 1:
           print("TextFieldイが押された\(textLength)")

           if (textLength >= 5) && (textLength < 10) {
             TextFieldABool = true
          } else {
             TextFieldABool = false
          }
          default:
            break
        }

}

これで複数のTextFieldにそれぞれ異なる条件を課したときの処理を記述することが出来ました。

ソースコード

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        let textLength = (textField.text! as NSString).replacingCharacters(in: range, with:            string).count

switch textField.tag {
        case 0:
           print("TextFieldアが押された\(textLength)")

           if textLength >= 4 {
             TextFieldABool = true
          } else {
             TextFieldABool = false
          }
        case 1:
           print("TextFieldイが押された\(textLength)")

           if (textLength >= 5) && (textLength < 10) {
             TextFieldABool = true
          } else {
             TextFieldABool = false
          }
          default:
            break
        }

}

private func checkButton() {
        if TextFieldABool && TextFieldBBool {
            loginButton.isEnabled = true
            loginButton.setTitleColor(UIColor.black, for: .normal)

        } else {
            loginButton.isEnabled = false
            loginButton.setTitleColor(UIColor.gray, for: .normal)

        }
    }//二つの真理値がともに真である時のみボタンを活性にして色を白、そうでない時ボタンを非活性にして色を灰色にする。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Swift バージョン確認

Swift バージョン確認

バージョンを確認する時のターミナルのコードをいつも忘れるのでメモしておきます。

因みにSwiftバージョンはlaunchpadアプリ(ロケット?みたいなアイコン)を開く → ターミナルで検索する → swift -v と入力すれば見れます。

以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む