質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.48%

複数のボタンをひとつのIBActionにつなげる方法 その3 (同じボタンがタップされた場合を見分ける方法)

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 736

score 100

 問題の概要

fuzzballさんとtyobigorouさんの助言で複数のボタンをひとつのIBActionにつなげる方法は解決しましたがその手法を使って次の課題に対応しました。

カギのボタンをタップしてtextFieldに記入済みの時間をキーボードを下げて保存し、カギイメージを解錠からロックに切り替える機能を持たせました。更にボタンをタップするとアラートが出てOKをタップするとtextFieldは空になり、キーボードがせり上がり記入できるようになり、カギイメージは解錠状態になる機能を実装しました。カギボタンは14個あります。

最初のボタンの場合は仕込んだとおりの機能を示しますが、2番目のボタンの場合は、アラートが出る状況から始まります。1番のボタンをスキップして2番目・・・14番目のボタンから始めると狙った機能どおり作動します。
下記のスクリーンショット画面で示すとおりです。

原因としては下記のコードのcount = count + 1が最初のボタンを続けてタップする場合と最初のボタン→2番目のボタンをタップすることを混同していると考えられます。

 状況を示すスクリーンショット

最初の画面
最初のボタンをタップ
2番目のボタンをタップしてアラートがでたところ
アラートのOKをタップした結果の画面

 原因を内蔵すると考えられるコード

var count = 0
    @IBAction func lockButtonTapped(_ sender: Any) {
        // ロックボタンを押した回数を1増やす
               count = count + 1
//略略略
  _ = displayImage()    

        guard let lockButtonTapped = sender as? UIButton else {
            return
        }
        //複数セルの場合のコード

       switch lockButtonTapped.tag {
        // Image Viewに読み込んだ画像をセット
        case 6:  //最初のボタン

            if count % 2 == 1  {
            print ("ここまで来た case 6")
           textTimeDep01DepCell01.isUserInteractionEnabled = false

                imageLockDep01DepCell01.image = UIImage(named: "KagiLock")
              print ("ここまで来た case 6ロック")
            }
                //残りが0の場合
                else if count % 2 == 0 {
           // アラートの実装
        let alert = UIAlertController(title: "記入済みの時刻を削除します。", message: "表示のOKを押すと削除されて新規に書き込みができます。このまま保存したい場合はキャンセルを押してください", preferredStyle: .alert)
            let cancelAction = UIAlertAction(title: "Cancel", style: .default)
            let okAction = UIAlertAction(title: "OK", style: .destructive) { (action: UIAlertAction) in
        //OKをタップするとイメージがオープンになり、textFieldが空になりキーボードが現れインプット可能になる
                self.imageLockDep01DepCell01.image = UIImage(named: "KagiOpen")
                self.textTimeDep01DepCell01.isUserInteractionEnabled = true
        self.textTimeDep01DepCell01.text = ""

                        }

        alert.addAction(cancelAction)
        alert.addAction(okAction)
        present(alert, animated: true, completion: nil)              
                    }

        case 7:  //2番目のボタン
            if count % 2 == 1  {
                print ("ここまで来た case 7")
//略略略
//case16から19まで続きます。            
        }

 試みた対策

上記の count = count + 1のコードにif文を入れて「同じボタンがタップされた場合」即ち「ボタンタブ番号が同じ場合」という条件を入れようとしました。トライしたコードは下記のとおりですが記入した条件コードが適切でないのかビルド結果は同じで先に進めないのでご教示ください。

 試みたコード

 ///////////// ロックボタン機能
  var count = 0
    @IBAction func lockButtonTapped(_ sender: Any) {

        //タップされたボタンのtag番号が同じなら
        // ロックボタンを押した回数を1つ増やす
        if [(sender as AnyObject).tag] ==
             [(sender as AnyObject).tag] {

        count = count + 1

        print ("ここまで来たIBAction lockImageに1を加える")
        }
        else {
            return
        }
        _ = displayImage()   

        guard let lockButtonTapped = sender as? UIButton else {
            return
        }

 ご参考事項

環境は下記のとおりです。
MacBook Pro (15-inch, 2016)
High Sierra OS10.13.6
Xcode Version 9.4 (9F1027a)Swift4

よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

鍵ボタンが14個あるのに対して、鍵チェックで利用しているcount変数が1つしかありませんよね。

ケース1)

1番目の鍵を押してロック。 => count = 1
1番目の鍵を押してロック解除。 => count = 2
【 count % 2 == 0 のため アラートが表示される 】

ケース2)

1番目の鍵を押してロック。 => count = 1
2番目の鍵を押してロック。 => count = 2
【 count % 2 == 0 のため アラートが表示されてしまう 】

今の実装を活かすのであれば、count変数も14個必要だと思います。

var counts: [Int] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

        switch lockButtonTapped.tag {
        case 6:  //最初のボタン
            if count[0] % 2 == 1  {
                // 省略
            } else if count[0] % 2 == 0 {
                    // 省略

        case 7:  //2番目のボタン
            if count[1] % 2 == 1  {
               // 省略

いかがでしょうか?

後からボタンを押した回数が必要になるのであればNGなのですが、
鍵ボタンの状態はon/off しかないので、

countが奇数だったらロック、偶数だったらロック解除


よりは

isLockがtrueだったらロック、falseだったらロック解除


など bool型を使った方が良いかもしれませんね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/21 18:39

    ありがとうございます。tappedされたtag番号を取得して同じ番号の場合とそうでない場合をif文にして追求していたのですが、上手く行きませんでした。教えて頂いた方法を目下試していますが、まだ成功していません。どこか私のコードがおかしのだと思います。また、ご報告します。
    var counts: (Int) = [0,0,0,0,0,0,0,0,0,0,0,0,0,0]でなく
    var counts: (Index) = [0,0,0,0,0,0,0,0,0,0,0,0,0,0]順番でも試してやっています。
    と定義すると、

    キャンセル

  • 2018/11/22 11:00

    教えて頂いた方法をやってみました。ただ、if count[0] % 2 == 1 {とするとエラーになるのでif counts[0] % 2 == 1 {でやりました。
    結果はどのボタンでもロック解除のアラートがでてロックはしませんでした。検証のため
    print (count)
    print (counts)
    を入れましたら
    0
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    1
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    と表示されます。

    キャンセル

  • 2018/11/22 11:12

    3つの方法を模索しています。3つめのCCCは不格好なコードですが成功をしています。
    AAA
    タップされたボタンの順番番号を取得するコードを使って
    if counts == counts {
    count = count + 1
    } else {
    count = count + 2
    }
    とする方法ですが、タップされたボタンの順番番号を取得するコードが分からず行き詰まっています。取得するコードを教えて頂ければ幸いです。
    BBB
    Arrayを使い、イメージがオープンしているなら、ロックのコード、もしイメージがロックされているならアラートを出して解錠するコード。これはエラーが続出して成功していません。
    CCC
    countは使わずに各caseに下記のコードを書きました。これは意図したとおりの機能になっています。
    if imageLockDep01DepCell01.image == UIImage(named: "KagiOpen") {
    textTimeDep01DepCell01.isUserInteractionEnabled = false

    imageLockDep01DepCell01.image = UIImage(named: "KagiLock")
    print ("ここまで来た case 6ロック")

    }
    else {
    // アラートの実装
    let alert = UIAlertController(title: "記入済みの時刻を削除

    //以下略略略略
    present(alert, animated: true, completion: nil)
    }

    キャンセル

  • 2018/11/22 11:16

    isLockがtrueだったらロック、falseだったらロック解除の方法も検討してみます。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Swiftに関する質問
  • 複数のボタンをひとつのIBActionにつなげる方法 その3 (同じボタンがタップされた場合を見分ける方法)