また1からこつこつと

最高はひとつじゃないと信じてまたがんばります。

UITableView周りいろいろ その②cellをタップしたときの処理

※2016/10/31追記 この記事はSwift1.x時代に書いたものなので情報が古いです

※2017/7/4追記 Swift3系で書き直した記事こちらです。 mjk0513.hateblo.jp

UITableViewの特定のcellをタップしたときに、画面遷移させたり値を変えたりさせたいときがあると思う。 iOSの設定画面なんてまさにそんな感じ。今回はその実装方法を紹介する。

didSelectRowAtIndexPath メソッドを使う

UITableViewは既に生成してあるものとして、コードとしては以下のようになる

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    let myTableView:UITableView = UITableView()
    
    let data:Array<String> = ["iPhone", "iPad", "iPod", "MacBook", "tv", "WATCH"]

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let width = self.view.frame.width
        let height = self.view.frame.height
        let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.height
        
        myTableView.frame = CGRectMake(0, statusBarHeight, width, height - statusBarHeight)
        myTableView.dataSource = self
        myTableView.delegate = self
        myTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
        self.view.addSubview(myTableView)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! UITableViewCell
        cell.textLabel?.text = data[indexPath.row]
        return cell
    }
    
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        println("\(data[indexPath.row])")
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }

}

追加したのは以下の部分

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        println("\(data[indexPath.row])")
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }

didSelectRowAtIndexPathってのが読んで字の如くタップされた時に呼び出される。その中に処理をかいてしまえばOK。今回は押されたセルの内容をprintln()してるだけだけど、例えば別のviewに遷移したいんだったら、

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        
        let nextVC:SecondViewController = SecondViewController()
        self.presentViewController(nextVC, animated: true, completion: nil)
        tableView.deselectRowAtIndexPath(indexPath, animated: true)

    }

と書けばよい。(PresentViewControllerで飛ばしちゃった) ちなみに、毎回書いている

tableView.deselectRowAtIndexPath(indexPath, animated: true)

は、セルをタップしたあとにハイライトを消すためのコードで、これがないとハイライトされっぱなしになってしまう。 これを意図的に実装しないというのは有りだけど、必要ない場合は必ずこの処理を入れること。そうしないとAppleの審査落ちます。

次回はUITableViewCellStyleについて考えます。