
【徒然iOS】気ままにUIKit26〜UITableView編集モード〜
概要
このマガジンは四十を過ぎたおっさんが、
を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。
今回
をやる〜〜〜!
前準備
念の為、バックアップ
新しいクラス
ビューコントローラの追加
イニシャルビューの変更
をいつも通りやってから本題へ💃

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

な感じで見やすく整理した〜〜〜!
後からSegueなんかでビューを繋いでいく時にこうやっておくと繋ぎやすくなるので💦
では、
本題
⒈テーブルビューを配置し、dataSource、delegate


⒉Prototype Cellsを1に変更

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

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


⒌アシスタントを開いて、各パーツを接続
ボタン: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を追加しておこう



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

下のエラーはいつも通り


上のエラーは、、、



⒎シミュレータで実行


⒏データ削除など、他のメソッドを追加
・データ削除
//テーブルビュー編集時に呼ばれるメソッド
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
//削除の場合、配列からデータを削除する。
if( editingStyle == UITableViewCellEditingStyle.Delete) {
dataList.removeAtIndex(indexPath.row)
}
//テーブルの再読み込み
tableView.reloadData()
}

一個一個また直す






下の処理のところは、エラー内容が
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)
に書き換えよう

再実行すると、、、

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



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


リンク先の記事は以上。
*ここまでのコード
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公式
さて、次回は
をやる予定。
あんまり使ったことないな💦