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

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

新規登録して質問してみよう
ただいま回答率
85.35%
iOS

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

Swift

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

Q&A

解決済

1回答

1151閲覧

Segmented Control tableView 切り替えについて教えてください。

Ytan

総合スコア39

iOS

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

Swift

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

1グッド

0クリップ

投稿2020/06/15 10:55

実現したいこと

SegmentedControlを以前初めて使いtableViewとともにビルドする事はできたのですが、このままだとcase1,case2でも同じtableViewのcellになってしまうと思うのですが、caseを切り替えることによって何もcellに情報がない空のtableviewをcase2にとりあえず作りたいです。

エラー文

Line 21
Editor placeholder in source file
Use of unresolved identifier 'handler'

上記2つのエラーが出てしまったのですが対処の仕方が分かりません。
本来handleSegmentChangeメソッドの後にSwichで配列の情報を分けたいのですが
息詰まってしましました。

該当コード

Swift

1import UIKit 2 3class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { 4 5 var data = ["a","b","c","d"] 6 let data2 = ["aaa","bbb","ccc"] 7 8 @IBOutlet weak var tableView: UITableView! 9 10 let segmentedControl: UISegmentedControl = { 11 let sc = UISegmentedControl(items: ["視聴前","視聴済"]) 12 sc.selectedSegmentIndex = 0 13 sc.addTarget(self, action: #selector(handleSegmentChange), for: .valueChanged) 14 return sc 15 }() 16 17 @objc fileprivate func handleSegmentChange(){ 18 print(segmentedControl.selectedSegmentIndex) 19 } 20 21 override func viewDidLoad() { 22 super.viewDidLoad() 23 // Do any additional setup after loading the view. 24 tableView.delegate = self 25 tableView.dataSource = self 26 27 } 28 29 func numberOfSections(in tableView: UITableView) -> Int { 30 return 1 31 } 32 33 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 34 return data.count 35 } 36 37 38 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 39 let cell = tableView.dequeueReusableCell(withIdentifier: "cell")! as UITableViewCell 40 cell.textLabel?.text = data[indexPath.row] 41 return cell 42 } 43 44 //cellをスワイプで削除 45 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { 46 if editingStyle == .delete { 47 data.remove(at: indexPath.row) 48 tableView.deleteRows(at: [indexPath], with: .fade) 49 } 50 } 51}

参考動画
参考、実現したい動画の内容です。

kazuki_user👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

特に難しいことはなく、たとえば下記のような感じでやってもらえれば実現できるかと思います。

が、

caseを切り替えることによって何もcellに情報がない空のtableviewをcase2にとりあえず作りたいです。

ここで意図することがよく読み取れませんでした。
もう少し詳しく説明することができれば考えてみたいと思います。

Swift

1import UIKit 2 3class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 4 let data = ["a","b","c","d"] 5 let data2 = ["aaa","bbb","ccc"] 6 // MARK: 空の配列を準備しておく 7 var selectedData = [String]() 8 9 @IBOutlet weak var tableView: UITableView! 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 14 tableView.dataSource = self 15 tableView.delegate = self 16 // Do any additional setup after loading the view. 17 // MARK: 初期設定は data1 18 selectedData = data 19 } 20 21 @IBAction func segmentSelected(_ sender: UISegmentedControl) { 22 switch sender.selectedSegmentIndex { 23 case 0: 24 // 視聴前 25 selectedData = data 26 case 1: 27 // 試聴後 28 selectedData = data2 29 default: 30 // 到達しないはず 31 fatalError("case でカバーできていません") 32 } 33 34 // MARK: 再読み込み 35 tableView.reloadData() 36 } 37 38 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 39 return selectedData.count 40 } 41 42 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 43 guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") else { 44 return UITableViewCell() 45 } 46 47 cell.textLabel?.text = selectedData[indexPath.row] 48 49 return cell 50 } 51 52}

guard-let文もif-let文でも最終的な処理は同じように書けますが、変数のスコープや見通しの良さが変わってくるという特徴があります。

Swift

1 guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") else { 2 return UITableViewCell() 3 } 4 5 // guard let の場合は特例で、中カッコ以降も宣言した変数は有効になる 6 cell.textLabel?.text = selectedData[indexPath.row] 7 8 return cell

dequeueReusableCell(withIdentifier:)で指定したセルがない場合nilが戻りますが、その場合は標準のセルを返す、という処理にするのであればguard-let文のほうが見通しが効くかと思います。

また、if-letfor-inなどとは違い、guard-let文は文中で宣言した変数の有効範囲がguard-let文以降でも有効になるという特徴もあるので、それを生かすことも可能です。

ちなみに、`if-let`文だとこのような感じになります。

Swift

1 if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") { 2 // オプショナルバインディングの場合、cell のスコープはこの中カッコまでとなる 3 cell.textLabel?.text = selectedData[indexPath.row] 4 5 return cell 6 } 7 8 return UITableViewCell()

今回は単純な例ですが、もしセルのプロパティを色々と設定するような場合を考えると、この書き方は見通しが悪い書き方になるのはご理解いただけるのではないでしょうか。

投稿2020/06/15 11:34

編集2020/06/17 05:17
TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ytan

2020/06/16 07:55

説明が曖昧ですみません。 意図している事は、Cellに入れる情報をSegmentでそれぞれ違うものを入れたいと言う事です。
Ytan

2020/06/16 08:17

やりたい処理が上記の処理でできました。 cellのところでguardを使うのですね、UITableViewCellにcastするか呼び出すのかによって何が変わるのですか?
TsukubaDepot

2020/06/17 05:19

guard-let文のことについては回答中に追記しましたので、ご確認いただければと思います。 > UITableViewCellにcastするか呼び出すのかによって何が変わるのですか? 「castするか呼び出すか」という部分ですが、具体的にどのような処理を指していますでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問