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

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

ただいまの
回答率

90.48%

  • Swift

    7502questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • Swift 2

    1334questions

    Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Swift iPhone 5でセルをタップしてもアクションシートが表示されない

解決済

回答 4

投稿 編集

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

eizi

score 5

下記のようにテーブルを表示させて、セル2をタップしたらアクションシートを表示させることをやっているのですが、iPhone5で検証するとセルタップの挙動が不信で行き詰まっています。

イメージ説明

下記の手順で動作をチェックすると、アクションシートがうまく表示される場合もありますが、
セル1タップ → セル2タップ

何回か繰り返していると、こんな挙動に見舞われます
セル1タップ → セル2タップ → アクションシートが表示されず、セル外かセル2をもう一度タップで表示

直接セル2を2回タップしてやっと表示される場合もあります。

iPhone 5のiOSは、9.2.1です。
シミュレーター、及びiPhone 6sのiOS 9.2.1の環境でも同様に確認したのですが、こちらは問題ありませんでした。

実装ではカスタムセルを使っています。
Xcode 7.2.1
Swift 2.1

//ViewController.swift

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    // セクション数
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    // 行数
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }

    // 表示
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // カスタムセル
        let cell = tableView.dequeueReusableCellWithIdentifier("tableCell") as! TableCell

        if indexPath.section == 0 {
            if indexPath.row == 0 {
                cell.textLabel?.text = "セル1"
            } else if indexPath.row == 1 {
                cell.textLabel?.text = "セル2"
            }
        }

        return cell
    }

    // セルがタップされた時の処理
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        if indexPath.section == 0 {
            if indexPath.row == 0 {
                print("セル1")
            } else if indexPath.row == 1 {
                showActionSheet()
                print("セル2")
            }
        }
    }

    func showActionSheet() {
        let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
        actionSheet.addAction(
            UIAlertAction(title: "項目1", style: UIAlertActionStyle.Default, handler: {(action) -> Void  in
            })
        )
        actionSheet.addAction(
            UIAlertAction(title: "項目2", style: UIAlertActionStyle.Default, handler: {(action) -> Void in
            })
        )
        let cancelAction =
            UIAlertAction(title: "キャンセル", style: UIAlertActionStyle.Cancel, handler: nil)

        actionSheet.addAction(cancelAction)

        self.presentViewController(actionSheet, animated: true, completion: nil)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
// TableCell.swift
import UIKit

class TableCell: UITableViewCell {

}

自分が持っているiPhone 5の不具合なのかなと考えてしまいますが、何かご存知の方、アドバイスを頂けたらです。
よろしくお願いいたします。

[追記 2016.3.24]
動画でみるとどんな挙動か分かりやすいです。
https://twitter.com/Ojehul/status/712843876868829184

現在、分かっていることは、Storyboard上でTable View CellのSelectionをNoneの設定をしているか、コード上で下記の設定を行うとこの現象が起きるようです。
cell.selectionStyle = UITableViewCellSelectionStyle.None

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • fuzzball

    2016/03/23 17:56

    セル2がグレーで選択状態になるのにアクションシートが表示されないのでしょうか? それとも、そもそも選択状態にならないのでしょうか?

    キャンセル

  • eizi

    2016/03/23 18:41

    返信ありがとうございます。 セル2が選択状態になるのにアクションシートが表示されないですね。 ただ、返信いただいた「グレーの選択状態」というのを見て、Storyboard上でTable View CellのSelectionをNoneにしていたのを思い出して、Defaultにしたら表示されるようになりました。 セルをタップしてもセルの背景をグレーではなく白のままにしたかったのでSelectionをNoneにしたのですが、コード上で制御しないとダメっぽいですね。 コード上でのアプローチをしてみたいと思います。 ありがとうございました!!

    キャンセル

回答 4

checkベストアンサー

+1

iPhone5の実機は持っていませんが、fuzzballさんのコメントでシミュレータでも発生するとのことでしたので、私もやってみました。
すると、確かにTable View CellのSelectionをNoneの設定をしているとこの現象が起きます。さらに、元の質問ではiPhone6sでは問題ないとのことでしたが、私の環境ではiPhone6sのシミュレータでも実機でも同じように問題発生しました。

さらにわかったことは、Table View CellのSelectionをDefaultにしていても、
セル2タップ → アクションシート表示 → セル外タップ → アクションシート消去 → 再度セル2タップ
とすると、やはりアクションシートが表示されない(fuzzballさんがコメントされている通り、実際にはアクションシートが数十秒遅れて表示される)現象が発生しました。

原因ははっきりと説明できませんが、おそらくdidSelectRowAtIndexPathのタイミングでアクションシートを表示すると、動作が不安定になるのだと思います。
(didSelectRowAtIndexPathだけでなく、タッチイベント呼び出しの延長でGUI処理をいろいろやると、不安定になる場合があることを経験しています。)

そこで、self.showActionSheet()の呼び出し処理を

dispatch_async(dispatch_get_main_queue(), { () -> Void in
    self.showActionSheet()
})


とし、一旦メインキューに回してからアクションシートを開いてみてください。
これで安定すると思います。私の環境では、これで問題なく動作するようになりました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/03/24 17:48

    安定して開くようになりました、ありがとうございます!

    パッと見、アクションシートを表示させるだけのそれほどの処理はしてないように思えたんですが、TakeOneさんのコメントからしてアクションシートそのものに問題がありそうに見受けられますので、少し使いドコロや代替案を考えてみたいと思います。

    本当に助かりましたありがとうございます!

    キャンセル

  • 2016/03/24 17:56

    念のためメインスレッドかどうかまでは調べていたのですが、どうせならdispatch_asyncまで試してみれば良かったです。(ちょっと悔しいw)

    キャンセル

0

Storyboard上でTable View CellのSelectionをNoneにしていると、iPhone 5ではこの現象が起きるようで、Defaultに戻したら解決しました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

ちょっと思ったのですが、Selection=Noneの状態で、セルをタップ出来たかどうかはどうやって判断したのでしょうか?
そもそもタップ出来ていないだけのような気もするので、以下のことを試してみて下さい。

・アクションシートが閉じきる前にタップしたときに「タップ出来ない」と思っているだけではないのか?
→ タップする間隔を長めにして確実にタップしてみる。

・iPhone5だと画面が小さいので正しくタップ出来ていないのではないか?
(画面の大きいiPhone6sや、マウスを使うシミュレータだと正確にタップ出来ているのではないか?)
→ セルの高さを高くしてみて試してみる。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/03/24 12:42 編集

    すみません、投稿時には入れてなかったですが、セルのタップはprint文で確認しました。

    // セルがタップされた時の処理
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath.section == 0 {
    if indexPath.row == 0 {
    print("セル1")
    } else if indexPath.row == 1 {
    showActionSheet()
    print("セル2")
    }
    }
    }

    実際に動画を撮ってみましたので、見てもらうと分かりやすいかと思います。
    https://twitter.com/Ojehul/status/712843876868829184

    一回目は問題なくアクションシートを表示できてますが、やはり二回目で表示されなくて、セル外の部分をタップするとアクションシートが表示されてしまいます。
    セルの高さも100と大きくしてあります。

    個別のセル内でこんな風にコードで制御すればいけるかなと思ったのですが、やはり同様の現象が出ててまだ頭を抱えてる状態です。
    cell.selectionStyle = UITableViewCellSelectionStyle.None

    よろしくお願いします。

    キャンセル

  • 2016/03/24 13:08 編集

    ちょっと追試して気付いたのですが、アクションシートが開かないのではなく、開くまでに時間が掛かるだけのようです。1分ほどして開いたことがありました。

    キャンセル

  • 2016/03/24 14:17

    うーん、セルがSelection=Defaultでもなるし、シミュレータでもなるし、機種とかOSは関係ないような気がしてきました。
    ・iPhone5 + iOS8.4.1(実機)
    ・iPhone5 + iOS9.2(シミュ)
    ・iPhone6s Plus + iOS9.2(シミュ)

    キャンセル

  • 2016/03/24 17:37

    なるほど、遅延してたんですね

    TakeOneさんのこのコードで安定して開くようになりました!!
    ```Swift
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
    self.showActionSheet()
    })
    ```
    ありがとうございます!!

    キャンセル

0

動画見ました。不思議な動きしてますね。
なんだか色々問題がありそうですが、

// セルがタップされた時の処理
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
        if indexPath.section == 0 {
            if indexPath.row == 0 {
            } else if indexPath.row == 1 {
                showActionSheet()
            }
        }
    }


ではどうでしょうか?

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/03/24 13:23

    ありがとうございます
    試してみましたが、やはりダメでした

    iOSのバージョンは同じなのに、機種で挙動が異なるものですね。。。

    キャンセル

  • 2016/03/24 13:25

    そうでしたか。。
    お力になれずすみませんでした…

    キャンセル

  • 2016/03/24 14:27

    いえ、こちらこそ基調なお時間をありがとうございます

    キャンセル

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

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

関連した質問

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

  • Swift

    7502questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • Swift 2

    1334questions

    Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。