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

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

ただいまの
回答率

88.13%

tableviewのセルを長押ししたときの処理

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,372

score 28

tableViewを使って、Windowsのエクスプローラのようなものをつくろうとしています。

あるフォルダの中身をtableViewで表示し、セルを選択したときに、選択したものがフォルダである場合は、選択したフォルダの中身を表示します。戻るボタンを押下すると、ひとつ前のフォルダに戻ります。

また、セルを長押ししたときに、セルを選択状態(背景色を変更など、視覚的にわかりやすい方法であればいいと思っています。)にし、削除ボタンを押下すると選択状態だったセルを削除します。

長押し時の処理で行き詰まったので、ご教授お願いします。
選択したセルのindexPathを取得することまではできたのですが、セル自体を変更する方法がわかりません。

以下、途中までのコードです。

import UIKit

class ViewController: UIViewController ,UITableViewDelegate , UITableViewDataSource,UIGestureRecognizerDelegate{

    //テーブルビューインスタンス作成
    var tableView :UITableView = UITableView()
    var button1 : UIButton = UIButton()
    var label1 : UILabel = UILabel(frame: CGRectMake(0, 260, 200, 20))

    //テーブルに表示するセルの配列を準備
    var items:[String] = []
    var items_sub : [String] = []

    //初回起動時のフォルダ準備
    var defaultFolder = "/Users/xxx/Desktop/Folder1/"

    //戻るボタン押下時の戻り先path
    var folder_pre1 = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        //テーブルビュー1の初期化
        tableView.frame = CGRectMake(0, 50, 200, 200)
        tableView.delegate = self
        tableView.dataSource = self
        self.view.addSubview(tableView)
        tableView.tag = 1
        getAllFile(defaultFolder)

        //戻るボタン1の初期化
        button1.setTitle("Back", forState: .Normal)
        button1.frame = CGRectMake(200, 50, 50, 20)
        self.view.addSubview(button1)
        button1.addTarget(self, action: "onClickButton1:", forControlEvents: .TouchUpInside)

        //ラベル1の初期化
        label1.text = defaultFolder
        self.view.addSubview(label1)
        label1.backgroundColor = UIColor.whiteColor()
        label1.font = UIFont.systemFontOfSize(8)

        //UILongPressGestureRecognizer(長押しイベント)宣言
        var longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "cellLongPressed:")
        longPressGestureRecognizer.delegate = self

        //tableviewにrecognizerを設定
        tableView.addGestureRecognizer(longPressGestureRecognizer)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //セルの行数
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }

    //セルの内容を変更
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

            let cell : UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")

            cell.textLabel?.text = items[indexPath.row]
            cell.detailTextLabel?.text = items_sub[indexPath.row]
            return cell
    }

    //セル選択時
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            var isDir = isDirectory(defaultFolder  + items[indexPath.row])
            if(isDir == true){
                folder_pre1 = defaultFolder
                defaultFolder = defaultFolder + items[indexPath.row] + "/"
                label1.text = defaultFolder
                println(defaultFolder)
                println(folder_pre1)
            }
            else{

            }
            getAllFile(defaultFolder)
            self.tableView.reloadData()

    }

    //セル長押し時
    func cellLongPressed(sender : UILongPressGestureRecognizer){
        //押された位置でcellのpathを取得
        let point = sender.locationInView(tableView)
        let indexPath = tableView.indexPathForRowAtPoint(point)

        if sender.state == UIGestureRecognizerState.Began{
            //セルが長押しされたときの処理

        }
        else{

        }

    }

    //button1押下時イベント
    func onClickButton1(sender:UIButton){
        label1.text = folder_pre1
        getAllFile(folder_pre1)
        defaultFolder = folder_pre1
        self.tableView.reloadData()
        println(folder_pre1)

        //1つ上の階層のpathに更新
        var endpoint = count(defaultFolder) - 1
        var path = (defaultFolder as NSString).substringToIndex(endpoint)
        var position = (path as NSString).rangeOfString("/",options:NSStringCompareOptions.BackwardsSearch).location
        println(position)
       println((count(folder_pre1)).description)
        folder_pre1 = (defaultFolder as NSString).substringToIndex(position + 1)
        println(folder_pre1)

    }

    //指定したPathがフォルダかどうか
    func isDirectory(path : String) -> Bool{

            var path = path

        var isDir :ObjCBool = false
        if NSFileManager.defaultManager().fileExistsAtPath(path, isDirectory: &isDir){
            if isDir{
                return true
            }
            else{
                return false
            }
        }
        else{
            return false
        }
    }

    //フォルダ1内のファイル一覧を取得
    func getAllFile(folder : String){
        let manager = NSFileManager.defaultManager()

        let defaultFolder = folder

        let list = manager.contentsOfDirectoryAtPath(defaultFolder, error: nil)!

        if(items.isEmpty == false){
                items.removeAll()
        }

        for path in list{
            items.append(path as! NSString as String)
            var fullPath = defaultFolder + (path as! String)

            let attribute : NSDictionary = manager.attributesOfItemAtPath(fullPath, error: nil)!

            let stringDate = changeToString(attribute.fileModificationDate()!)
            items_sub.append(stringDate + " / " + attribute.fileSize().description)
            }
        }

  //NSDateをString型に変更
    func changeToString(date : NSDate) -> String{
        let date  = date
        let formatter = NSDateFormatter()
        formatter.dateFormat = "yyyy-MM-DD HH:mm:ss"

        let stringDate :String = formatter.stringFromDate(date)

        return stringDate
    }

}

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

0

選択したセルのindexPathを取得することまではできたのですが、セル自体を変更する方法がわかりません。

長押しした時点で対象セルの背景色を変更することも可能ですが、それだとセルを表示領域の外にスクロールして、再度表示領域に戻した時に新しい別のセルを使って再表示するので、背景色は元に戻ってしまいます。逆に背景色を変更したセルが別のセルで再利用された時に、長押ししてないのに最初から背景色が変更された状態になる可能性もあります。

こういうことをしたい時は、選択状態を保持した配列をプロパティで持ち、長押しした時に対象行を選択済みにします。
そして、
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellのメソッドの中で選択状態に応じてcellの背景色を設定すればよいです。

ちなみに、「Windowsのエクスプローラのようなものをつくろうとしています」とのことですが、UIKit Frameworkを使っているということは、iOS用アプリを作ろうとしているのですよね?
iOS用アプリは、アプリの外のファイルやフォルダにアクセスできないことは理解されていますか?
つまり、自分が格納したファイルやアプリ内部のライプラリで格納したファイル以外にはアクセスできないので、Windowsのエクスプローラーのようにシステムファイルや他のアプリのファイルにはアクセスできませんよ。セキュリティ観点から、iOSはそのあたりのファイルアクセスを厳しく制限しています。(シミュレータで動作させる場合は、Macのアクセス制限で動作しますので、アプリの外のファイルにもアクセスできますが、実機ではできません。)

アプリ作成の勉強とアプリ内部のフォルダ構成の勉強を兼ねて作ろうとしているのでしたらとても勉強になると思いますが、Windowsのエクスプローラーのように便利なものにはならないと思いますよ。開発や調査のためにアプリ内部のファイルを参照したかったらXcodeのDeviceメニューから参照できます。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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