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

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

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

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

1回答

1106閲覧

UITableView上のSegmentedControlの状態を取得したい。

Masa_teratail

総合スコア9

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2020/04/25 17:52

現在、アンケートアプリを作成しています。
UITableViewのcellに、UILabelの質問番号、質問文(配列)と、SegmentedControlの「はい・いいえ」の選択肢を設置しています。
TableView最下段の回答終了ボタンを押した際に、はいの数といいえの数を取得したいです。

現在、はい・いいえの値が変わったタイミング(.valueChanged)で、SegmentIndexを取得し、回数を加算しているのですが、はい・いいえを切り替えるごとに加算されてしまい、正確な合計を計算できません。

どのようなコードで上記を実装できるか、また、もしよりよい方法があれば、ご教示願えればと思います。
よろしくお願いいたします。

Swift5

1 func numberOfSections(in tableView: UITableView) -> Int { 2 return 1 3 } 4 5 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 6 return QuestionnaireArray.count 7 } 8 9 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 10 11 //セルの再利用 12 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath) 13 14 // フォント設定 15 cell.textLabel!.font = UIFont(name: "Arial", size: 35) 16 17// Labelの内容 18 let numberLabel = cell.viewWithTag(1) as! UILabel 19 numberLabel.text = String("(number + indexPath.row + 1)") 20 21 let questionnaireLabel = cell.viewWithTag(2) as! UILabel 22 questionnaireLabel.text = String("(questionnaireArray[indexPath.row])") 23 24// はい/いいえのsegmentedControl 25 let answerButton = cell.viewWithTag(3) as! UISegmentedControl 26 27 let font = UIFont.systemFont(ofSize: 25) 28 answerButton.setTitleTextAttributes([NSAttributedString.Key.font: font], for: .normal) 29 answerButton.selectedSegmentIndex = -1 30 31 answerButton.addTarget(self, action: #selector(segmentValueChanged(_:)), for: .valueChanged) 32 33 return cell 34 } 35 36// はい、いいえのカウント 37 @objc func segmentValueChanged(_ sender: UISegmentedControl) { 38 39 switch sender.selectedSegmentIndex { 40 case 0: 41 yesAnswerCount = yesAnswerCount + 1 42 43 case 1: 44 noAnsewerCount = noAnsewerCount + 1 45 46 default: 47 break 48 } 49 } 50 51// 回答終了ボタン 52// 選択されたはい、いいえの数を数える。 53// 回答がはいの行番号を取得する 54// 未回答がないかをチェック → あったら警告メッセージ表示(+サウンド) 55// 未回答がなかったら → 結果をResultVCに送る 56 @IBAction func finishButton(_ sender: Any) { 57 } 58

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

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

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

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

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

guest

回答1

0

ベストアンサー

適当に書くと↓みたくなると思うけど、

swift

1@objc func segmentValueChanged(_ sender: UISegmentedControl) { 2 switch sender.selectedSegmentIndex { 3 case 0: 4 yesAnswerCount += 1 5 noAnsewerCount -= 1 6 case 1: 7 yesAnswerCount -= 1 8 noAnsewerCount += 1 9 default: 10 break 11 } 12}

セルが使い回されているので、SegmentedControlの状態を保持する配列かなにかに値をもたせて、そちらをカウントしないとうまく行かないんじゃないかな?
それとSegmentedControlの初期値(値なし/はい/いいえ)によってコードが変わってくると思います。


追記:こんな流れかな〜
segmentedControlの値が変更されると、didSet内が実行されるので、labelの値を変えるなりそこですればリアルタイム?に値を全体の値に反映させることができると思います。

swift

1enum SegmentedControlStatus: Int { 2 case none = -1 3 case yes = 0 4 case no = 1 5} 6 7protocol TableViewCellDelegate: AnyObject { 8 func valueChanged(cell: UITableViewCell, value: SegmentedControlStatus) 9} 10 11class CustomCell: UITableViewCell { 12 13 weak var tableViewCellDelegate: TableViewCellDelegate? 14 15 @IBOutlet weak var segmentedControl: UISegmentedControl! 16 17 func segmentedControlValueChanged(_ sender: UISegmentedControl) { 18 let value 19 = SegmentedControlStatus(rawValue: sender.selectedSegmentIndex) ?? .none 20 21 tableViewCellDelegate?.valueChanged(cell: self, value: value) 22 } 23 24} 25 26 27class ViewController: UIViewController, UITableViewDateSource, TableViewCellDelegate { 28 29 var numOfYes: Int = 0 30 var numOfNo : Int = 0 31 32 var segmentedControlStatuses = [SegmentedControlStatus]() { 33 didSet { 34 if oldValue != segmentedControlStatuses { 35 numOfYes = segmentedControlStatuses.filter { $0 == .yes }.count 36 numOfNo = segmentedControlStatuses.filter { $0 == .no }.count 37 } 38 } 39 } 40 41 // CellForRowAt内 42 cell.tableViewCellDelegate = self 43 let segmentedControlStatsu = segmentedControlStatuses[indexPath.row] 44 cell.segmentedControl.selectedSegmentIndex = segmentedControlStatsu 45 46 47 48 func valueChanged(cell: UITableViewCell, value: SegmentedControlStatus) { 49 guard let index = tableView.indexPath(for: cell)?.row else { return } 50 51 segmentedControlStatuses[index] = value 52 53 } 54}

投稿2020/04/25 18:18

編集2020/04/26 09:32
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Masa_teratail

2020/04/26 05:18

ありがとうございます。 ご助言の通り、初期値を「はい」にすることで合計を計算することができました。 本当は回答忘れをみつけるため、SegmentedControlの初期値を「選択なし」にできるといいのですが、ご指摘の通り、処理が複雑になりそうですね。 任意の時点でのselectedSegmentIndexを取得できるといいのですが。。 Swiftではないのでよく理解できませんでしたが、以下のサイトでは、やはりreuseをやめて処理をするようなことが書いてあるようでした。 https://stackoverflow.com/questions/20589512/get-segmentedcontrol-value-from-tableviewcells
Masa_teratail

2020/04/26 14:26

どうもありがとうございます。 サンプルコードまでアップしていただき感謝いたします。 トライしてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問