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

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

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

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

Xcode

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

Swift

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

Q&A

解決済

2回答

2438閲覧

【swift】TablevVewで特定Cellを非表示(高さを0)にして、詰めて表示するにはどうしたらいいでしょうか。

HNSZ

総合スコア33

TableView

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

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/11/15 08:42

編集2018/11/17 08:29

TableViewに関して質問があります。
勉強会やカンファレンス等のイベント情報を閲覧できるアプリをご想像下さい。

イベント一覧をTableViewに表示していますが、そのviewのまま、
UISwitchのON/OFFで、一覧の中より参加済イベントのみ表示する/全て表示する と
切り替えられるように変更したいです。

参加済みか否かは「dict["PointPaid"]」に数値が入っているか否かで判断しています。

cell.isHiddenで非表示にすることはできたのですが、
非表示にした箇所が空白で空いており不格好です。

非表示かつ、高さを0にして詰めて表示したいです。
heightForRowAt内でできそうな気がするのですが、記述方法が探せませんでした、、、
アドバイスいただける幸いです。

var onlyPaid:Bool = false //スイッチ判断 var items = [NSDictionary]() //イベント情報辞書 @IBOutlet var `switch`: UISwitch! //スイッチ判断 @IBOutlet var tableView: UITableView! @IBAction func onSwitch(_ sender: UISwitch) {  //スイッチ切り替え、テーブル再読込 onlyPaid = sender.isOn tableView.reloadData() } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { displayHeight = self.view.frame.height return displayHeight / 9 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "VotedContentTableViewCell") as! VotedContentTableViewCell let dict = items[(indexPath as NSIndexPath).row] let resultPoint = dict["PointPaid"] as? Int let resultButton = cell.viewWithTag(1) as! UIButton if onlyPaid == false{  //全て表示 if resultPoint != nil{ resultButton.backgroundColor = .purple }else{ resultButton.backgroundColor = .gray } } else { //参加済みのみ表示 if resultPoint == nil{ cell.isHidden = true //参加済みでない為、isHidden = true }else{ resultButton.backgroundColor = .purple //参加済み } return cell } override func viewDidLoad() { self.tableView.register(UINib(nibName: "VotedContentTableViewCell", bundle: nil), forCellReuseIdentifier: "VotedContentTableViewCell") //tableview tableView.delegate = self tableView.dataSource = self tableView.separatorStyle = .none //firebase if let userID = userid{ firebaseFunction.observeDataByNSDict( FirebaseURL:"https://firebaseio.com/User/(userID)/ParticipationContent"){ items in self.items = items self.tableView.reloadData() } } super.viewDidLoad() }

<追記>高さを条件分岐

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { if onlyPaid == false{ return displayHeight / 9 } else { let dict = items[(indexPath as NSIndexPath).row] if dict["PointPaid"] as? Int == nil{ return 0.01 } else{ return displayHeight / 9 } } }

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

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

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

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

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

guest

回答2

0

高さを更新するときにはtableViewかcellを更新してください(reloadDataなど)
なお高さ0は許可されていなく、0.1などとします

投稿2018/11/15 08:52

kosanai

総合スコア471

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

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

HNSZ

2018/11/17 08:31

いつもアドバイス頂きましてありがとうございます! 本文に追記しておりますが、高さを条件分岐でわけて非表示にすることができました。 ただし、heightForRowAtと、cellForRowAtで同じ記述をしており非効率に感じています。 「 let dict = items[(indexPath as NSIndexPath).row] if dict["PointPaid"] as? Int == nil 」 こちら、heightForRowAt内で省略することはできないでしょうか?
kosanai

2018/11/18 07:21 編集

通常は、fuzzballさんの言う通りcellを出すかどうかを何らかの方法で決定し、reloadDataをかけます。section、cellの構成をいじることでcellの出し分けができるのがtableViewの利点の一つです。そして最も基本的な方法です(方法1) 構成の変更については、indexPathの管理が若干面倒です。 最近私がやってる管理方法(方法1の追加の工夫) https://qiita.com/netetahito/items/2e340e5d8503731bd105 今ならStackViewにしてしまう手もあります。StackViewはViewをisHiddenにすると要素が詰められるので便利です(方法2) ただUITableViewとはまたやり方がガラッと変わるので別のハマりポイントもあります。 ちなみに世の中に何故StackViewの解説が少ないかと言えば、使用できるのがiOS9以降でかなり新しいからです。 話をUITableViewに戻して、アニメーションをしようとし始めると難易度が上がります。 最近分かりやすかったのはこれです(方法3) https://qiita.com/KikurageChan/items/71d4e1e84d039d1e2f5a
HNSZ

2018/11/20 08:12

kosanai様 色々と方法のご教示ありがとうございます! 足りない知識ばかりで。。とても勉強になりました。 まずはできる範囲でfuzzball様の方法1で実装できました。 ありがとうございました。
kosanai

2018/11/20 10:25

???? ここ結構ハマります
guest

0

ベストアンサー

表示ONのアイテムを抽出して、それをTableViewに与えて下さい。

コード追記

swift

1var joinedItems = [NSDictionary]() //参加済アイテム保存用 2var items = [NSDictionary]() { 3 didSet { 4 //itemsn更新時にjoinedItemsを生成し直す 5 joinedItems = items.filter {$0["PointPaid"] as? Int != nil} 6 } 7}

という仕組みで、自動的に表示ONのアイテムを抽出できるので、これをTableViewに与えてください。

  • セル数取得 items.countjoinedItems
  • セル生成時 items[indexPath.row] → joinedItems[indexPath.row]

動作確認

swift

1items += [ 2 ["id": 0, "PointPaid": 123], 3 ["id": 1], 4 ["id": 2, "PointPaid": "abc"], 5] 6print(joinedItems) 7/* 8[{ 9 PointPaid = 123; 10 id = 0; 11}] 12*/ 13 14items.append(["id": 3, "PointPaid": 999]) 15print(joinedItems) 16/* 17[{ 18 PointPaid = 123; 19 id = 0; 20}, { 21 PointPaid = 999; 22 id = 3; 23}] 24*/ 25 26items.remove(at: 0) //id0削除 27print(joinedItems) 28/* 29[{ 30 PointPaid = 999; 31 id = 3; 32}] 33*/

ひとりごと

参考にした記事が古いんだと思いますが、NSDictionaryではなくDictionaryの方がいいし、いちいちIndexPathをNSIndexPathにキャストしなくていいです。

投稿2018/11/15 09:40

編集2018/11/19 01:21
fuzzball

総合スコア16731

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

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

HNSZ

2018/11/20 08:04

fuzzball様 いつもありがとうございます! >var items = [NSDictionary]() {   didSet { この書き方をできることを知りませんでした。。 とても勉強になりました。 追記いただいたコードで実装できました。 >NSDictionaryではなくDictionaryの方がいいし そうだったのですね。。全体でNSDictionary使っていたので 見直したいと思います! ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問