見出し画像

【徒然iOS】気ままにUIKit26〜UITableView編集モード〜

概要

このマガジンは四十を過ぎたおっさんが、

を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。

今回

をやる〜〜〜!

前準備

  1. 念の為、バックアップ

  2. 新しいクラス

  3. ビューコントローラの追加

  4. イニシャルビューの変更

をいつも通りやってから本題へ💃

こんな感じ

本題の前に、、、

だいぶビューの数も増えてきて横に長くなってきたから、
今までに作ったビューを

上から、AutoLayout以前、中がAutoLayout、下がTableViewで整理

な感じで見やすく整理した〜〜〜!
後からSegueなんかでビューを繋いでいく時にこうやっておくと繋ぎやすくなるので💦
では、

本題

⒈テーブルビューを配置し、dataSource、delegate

こんな感じで
できたのを確認

⒉Prototype Cellsを1に変更

⒊Table View Cellをクリックし、IdentifierにCellの名前を入力

今回はEditCellにした〜〜〜

⒋切り替え用のボタンを配置

部品のライブラリから〜〜〜
一旦こんな感じで配置して〜〜〜

⒌アシスタントを開いて、各パーツを接続

  • ボタン:changeModeButtonって名前でアクション接続

  • テーブルビュー:editableTableViewて名前でアウトレット接続

ボタン
テーブルビュー
てな感じ〜〜〜〜

⒍コードを追加

今回追加する箇所は

    //データ
    var dataList = ["青山","阿部","加藤","神田","佐藤","坂田"]
 
    //データを返すメソッド
    func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath:NSIndexPath) -> UITableViewCell {
        
        //セルを取得する。
        let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath:indexPath) as UITableViewCell
        
        cell.textLabel?.text = dataList[indexPath.row]
        
        return cell
    }
 
 
    //データの個数を返すメソッド
    func tableView(tableView:UITableView, numberOfRowsInSection section:Int) -> Int {
        return dataList.count
    }
 
 
    //ボタン押下時に呼ばれるメソッド
    @IBAction func changeMode(sender: AnyObject) {
        //通常モードと編集モードを切り替える。
        if(testTableView.editing == true) {
            testTableView.editing = false
        } else {
            testTableView.editing = true
        }
    }

だけど、先にいつものように

UITableViewDataSourceプロトコル

をクラスに追加して、stubsを追加しておこう

FIXをクリック〜〜〜
必要なメソッドが追加されたので〜〜〜
わかりやすい位置にメソッドを移動した〜〜〜

では、コードを直してく〜〜〜
コードのTestCellとかテーブルビュー名だけを今回の名前に変更して
組み込むと、

こんな感じのエラーになる

下のエラーはいつも通り

FIXをクリックして
消えましたな👀

上のエラーは、、、

isEditingに書き方が変わっただけみたいなのでFIX
他も同様なので、まとめてFIXして〜〜〜
完了

⒎シミュレータで実行

出てきた
出来た様子🕺

⒏データ削除など、他のメソッドを追加

・データ削除

//テーブルビュー編集時に呼ばれるメソッド
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
 
   //削除の場合、配列からデータを削除する。
   if( editingStyle == UITableViewCellEditingStyle.Delete) {
       dataList.removeAtIndex(indexPath.row)
   }
  //テーブルの再読み込み
      tableView.reloadData()
}
普通にはめ込むだけだと、エラー発生

一個一個また直す

とりあえずFIXを上から押す〜〜〜
ひとつめは消えたからふたつめ
メソッド宣言部のエラーは消えたね👀
上からFIXしていこう
消えたね〜〜〜

下の処理のところは、エラー内容が

Value of type '[String]' has no member 'removeAtIndex'
そんな処理いないよ

ってことみたいだから

//変更前
dataList.removeAtIndex(indexPath.row)            

//変更後
dataList.remove(at: indexPath.row)

に書き換えると、

エラーが消える

シミュレータで実行

反応がないね👀

と、実は理由は簡単で、
上の黄色エラーのFIXがPrivateに書き換えているだけで間違っているから〜〜〜

なので、JumptoDefinitionで現在の仕様を確認

こいつだとわかるので
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath)

に書き換えよう

書き換えた

再実行すると、、、

実行できたね

とまあ、後の要領は大体同じかな

削除できるデータを制限する
データの並び替え
並び替えできるデータを制限する

編集モードでデータを選択できるようにする
をやって

Editingを「Single Selection During Editing」に変更
できたね

リンク先の記事は以上。

*ここまでのコード

class TableEditModeViewController: UIViewController, UITableViewDataSource {
    //データ
    var dataList = ["青山","阿部","加藤","神田","佐藤","坂田"]
    @IBAction func changeModeButton(_ sender: UIButton) {
        //通常モードと編集モードを切り替える。
        if(editableTableView.isEditing == true) {
            editableTableView.isEditing = false
        } else {
            editableTableView.isEditing = true
        }
    }
    @IBOutlet weak var editableTableView: UITableView!
    //データの個数を返すメソッド
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    //データを返すメソッド
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "EditCell", for:indexPath) as UITableViewCell
        cell.textLabel?.text = dataList[indexPath.row]
        return cell
    }
    //テーブルビュー編集時に呼ばれるメソッド
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        //削除の場合、配列からデータを削除する。
        if( editingStyle == UITableViewCell.EditingStyle.delete) {
            dataList.remove(at: indexPath.row)
        }
        //テーブルの再読み込み
        tableView.reloadData()
    }
    //編集可否を答えるメソッド:下の並び替え可否を答えるメソッドと競合するのでいずれかのみ
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        //最初の2行は削除不可にする。
        if(indexPath.row < 2) {
            return false
        } else {
            return true
        }
    }
    //並び替え時に呼ばれるメソッド
    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath){
        //移動されたデータを取得する。
        let moveData = tableView.cellForRow(at: sourceIndexPath as IndexPath)?.textLabel!.text
        //元の位置のデータを配列から削除する。
        dataList.remove(at: sourceIndexPath.row)
        //移動先の位置にデータを配列に挿入する。
        dataList.insert(moveData!, at: destinationIndexPath.row)
    }
    //並び替え可否を答えるメソッド:上の編集可否を答えるメソッドと競合するのでいずれかのみ
    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        let orderData = dataList[indexPath.row]
        //青山さん以外の行は並び替え不可にする。
        if(orderData != "青山") {
            return false
        } else {
            return true
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

ブラッシュアップ

ここからブラッシュアップ

⒈ボタンの表示名を編集onとoffで切り替えたい

・ボタンをアウトレットでも接続後、コードを以下に追記変更

class TableEditModeViewController: UIViewController, UITableViewDataSource {
    //データ
    @IBOutlet weak var editButton: UIButton!//アウトレット接続
    var dataList = ["青山","阿部","加藤","神田","佐藤","坂田"]
    @IBAction func changeModeButton(_ sender: UIButton) {
        //通常モードと編集モードを切り替える。
        if(editableTableView.isEditing == true) {
            editableTableView.isEditing = false
            editButton.setTitle("編集on", for: .normal)//追加
        } else {
            editableTableView.isEditing = true
            editButton.setTitle("編集off", for: .normal)//追加
        }
    }
    @IBOutlet weak var editableTableView: UITableView!
    //データの個数を返すメソッド
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    //データを返すメソッド
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを取得する。
        let cell = tableView.dequeueReusableCell(withIdentifier: "EditCell", for:indexPath) as UITableViewCell
        cell.textLabel?.text = dataList[indexPath.row]
        return cell
    }
    //テーブルビュー編集時に呼ばれるメソッド
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        //削除の場合、配列からデータを削除する。
        if( editingStyle == UITableViewCell.EditingStyle.delete) {
            dataList.remove(at: indexPath.row)
        }
        //テーブルの再読み込み
        tableView.reloadData()
    }
    //編集可否を答えるメソッド:下の並び替え可否を答えるメソッドと競合するのでいずれかのみ
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        //最初の2行は削除不可にする。
        if(indexPath.row < 2) {
            return false
        } else {
            return true
        }
    }
    //並び替え時に呼ばれるメソッド
    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath){
        //移動されたデータを取得する。
        let moveData = tableView.cellForRow(at: sourceIndexPath as IndexPath)?.textLabel!.text
        //元の位置のデータを配列から削除する。
        dataList.remove(at: sourceIndexPath.row)
        //移動先の位置にデータを配列に挿入する。
        dataList.insert(moveData!, at: destinationIndexPath.row)
    }
    //並び替え可否を答えるメソッド:上の編集可否を答えるメソッドと競合するのでいずれかのみ
    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        let orderData = dataList[indexPath.row]
        //青山さん以外の行は並び替え不可にする。
        if(orderData != "青山") {
            return false
        } else {
            return true
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        editButton.setTitle("編集on", for: .normal)//追加
    }
}

シミュレータを実行すると

できた

⒉AutoLayoutの制約を追加

あとは、いつもどおり

ボタンとテーブルビューを両方選んで、制約と追加
制約追加後実行して
問題ないことを確認ずみ

以上です〜〜〜〜!🕺

まとめ

これであとは、データベース機能と連携して編集後のテーブルの状態を保存するかどうかで、よく目にするテーブルアプリのイメージが湧くかな💦

Apple公式

さて、次回は

をやる予定。
あんまり使ったことないな💦

いいなと思ったら応援しよう!