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

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

ただいまの
回答率

90.62%

  • Swift

    7007questions

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

  • iOS

    3889questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

【iOS,Swift】選択されたCellの種類によって画面遷移先を振り分ける処理

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,239

Kesth

score 75

UITableViewController+UINavigationControllerによる
画面遷移の方法について質問させてください。

まずはじめに、UITableViewController+UINavigationControllerの画面遷移の方法は
下記の様なdidSelectRowAtIndexPathプロパティの中でpushViewControllerを
定義して画面遷移させる方法が一般的だと思います。

    func tableView(tableView: UITableView, didSelectRowAtIndexPath index
Path: NSIndexPath) {
       
     switch indexPath.row{
            case 1:
               self.navigationController?.pushViewController(HogeViewController(), animated: true)
            default:
                break
        
        }   
 }
    
上記の方法は、既に各indexPath.rowに格納されるセルが固定の場合は
使えますが、それぞれの列に格納される種類が変動する場合には
使用できません。
(例えば、アプリの設定画面などで使用されているUITableViewControllerの場合は
表示の順序が固定のため上記方法が適用できますが、SNSの通知画面など
表示されるセルが動的に変化する場合は使用できないと思います)

その上で、今回質問させていただきたいのは、表示されるセルの順序が動的に変化する場合においてユーザーがタップしたセルの種類によって遷移先の画面を振り分ける方法についてです。

例えば、UITableViewControllerに表示されるHogeCell1, HogeCell2, HogeCell3という3種類のカスタムセルがあり、それぞれの遷移先をHogeVC1, HogeVC2, HogeVC3とした場合、どのような処理を書けばよろしいでしょうか?

現在下記のようなコードを書いていますが、画面遷移が発生しないので
ご教授頂ければ幸いです。

よろしくお願いします。

※追記
下記のコードを試したのですが、let hogeCell1 = 〜のところで
「Thread1: signal SIGABRT」のエラーが出てしまいました。
どこが間違っているでしょうか?


    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        
        let hogeCell1 = tableView.cellForRowAtIndexPath(indexPath) as! HogeCell1()
        let hogeCell2 = tableView.cellForRowAtIndexPath(indexPath) as! HogeCell2()
        let hogeCell3 = tableView.cellForRowAtIndexPath(indexPath) as! HogeCell3()
        
        switch indexPath.row{
            case hogeCell1:
                self.navigationController?.pushViewController(HogeVC1(), animated: true)
            case hogeCell2:
                self.navigationController?.pushViewController(HogeVC2(), animated: true)
            case hogeCell3:
                self.navigationController?.pushViewController(HogeVC3(), animated: true)
        
            default:
                break
        
        }
    
    }
 
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

下記のコードを試したのですが、let hogeCell1 = 〜のところで 
「Thread1: signal SIGABRT」のエラーが出てしまいました。 
どこが間違っているでしょうか? 

これは、tableView.cellForRowAtIndexPath(indexPath)で得られたオブジェクトがHogeCell2クラスかHogeCell3クラスなのに、HogeCell1クラスを格納する変数に代入しようとしたから例外が発生したのだと思います。

例えば、UITableViewControllerに表示されるHogeCell1, HogeCell2, HogeCell3という3種類のカスタムセルがあり、それぞれの遷移先をHogeVC1, HogeVC2, HogeVC3とした場合、どのような処理を書けばよろしいでしょうか?

選択されたセルのクラスに応じて遷移するViewControllerを変えたいなら、一旦UITableViewCellクラスの変数にセルオブジェクトを代入して、isKindOfClassで実際のクラスを調べればできます。
次のような感じです。
let cell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell!
if cell.isKindOfClass(HogeCell1) {
    self.navigationController?.pushViewController(HogeVC1(), animated: true)
} else if cell.isKindOfClass(HogeCell2) {
    self.navigationController?.pushViewController(HogeVC2(), animated: true)
} else if cell.isKindOfClass(HogeCell3) {
    self.navigationController?.pushViewController(HogeVC3(), animated: true)
}
ただ一般的には、テーブル表示が動的に変化するということは、そのテーブル表示の元となっているデータの順序も動的に変化しているはず(というか、元データが示した順序通りにテーブル表示されているはず)です。であれば、indexPathに対応する元データを取得し、その元データに入っている情報を見て適切なViewControllerに遷移すればよい話だと思います(テーブル表示処理で、指定されたindexPath位置のカスタムセルを元データを見て選択したのと同じように、遷移先のViewControllerも元データを見て選択すればよい話だと思います)。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/10/13 22:55

    お返事が遅くなってしまいすみません。
    コメントありがとうございます!
    isKindOfClassを使った方法はとてもシンプルでいいですね。
    シンプルで理解しやすいのでベストアンサーにさせて頂きました。

    キャンセル

0

同じようなコードを書いたことがあります。
結論から言うと、動的に並び替えを行うメソッド上で配列の順番を並び替えて実装できます。

以下はtableViewのsetEditing機能を使って実装する時ですが、
移動前と移動後のindexPathが取得できますので、以下のように実装が可能です。

//contents:String[] = {'a','b','c','d','e'}
//sourceIndexPath = 0
//destinationIndexPath = 3 だったとして、、

func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
        let src:Int = sourceIndexPath.row //簡単のため、変数名をわかりやすくしておきますね。
        let dst:Int = destinationIndexPath.row

        let cacheF:String = contents[src] as! String // srcの位置にある値をキャッシュ
        contents.removeObjectAtIndex(src) //srcの位置にある値を削除
        contents.insertObject(cacheF, atIndex: dst) //dstの位置にキャッシュした値を格納
        tableViewObject.reloadData()    //テーブル更新
    }

// 上記のメソッドを通ると、 contents = {'b','c','d','a','e'} となっているはずです。

私の場合は配列の中身がStringでしたが、
これをViewControllerのインスタンスにすれば要件の動作ができると思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2015/10/13 22:53

    お返事が遅くなってしまい、すみません!
    コメントありがとうございます。
    コメントアウトを多用して頂きとても丁寧に書いてもらって
    大変ありがたいのですが、僕の理解がまだ進まない部分がありましたので
    上の方をベストアンサーにさせて頂きました。
    これからもよろしくお願いします。

    キャンセル

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

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

関連した質問

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

  • Swift

    7007questions

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

  • iOS

    3889questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。