🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

TableView

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

Xcode

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

Swift

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

Q&A

解決済

3回答

2318閲覧

UITableViewControllerのCellが更新できない

rea_sna

総合スコア32

Realm

RealmとはSQLiteやCore Dataに代わるモバイルデータベースです。iOSとAndroidの両方でサポートされています。

TableView

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

Xcode

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

Swift

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

0グッド

0クリップ

投稿2021/01/30 14:35

編集2021/01/30 14:39

前提

XLPagerTabStripを使ったToDoリスト的なアプリを開発しています。

Xcode12.4

実現したいこと

realmに保存したToDoデータを取り出し、UITableViewControllerで表示していますが、データ追加後にデータが更新されません。
viewDidload時や、別のタブに行って戻ってくる(willapper時)にはデータが更新されます。

該当のソースコード

XLPagerTabStripを使用しているため、VC構造がやや複雑になっています。

<Storyboard> ScroolViewが配置されているところに1〜4のVCが入るという感じです。 ![イメージ説明](f5c26850c3a24c422de59e8998aba001.png)

<VCのコード>

Swift

1------------------------------------------------------------------------------------ 2ViewController.swift】(上のStoryboardのキャプチャでは、scrollViewが配置されている部分になります) 3------------------------------------------------------------------------------------ 4 5 6let usdf = UserDefaults.standard 7 8@IBAction func addTapped(_ sender: Any) { 9 let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert) 10 11 12 <中略(アラートタイトル)> 13 14 15 alert.addTextField(configurationHandler: {(textField) -> Void in 16 textField.delegate = self 17 18 }) 19 20 //追加ボタン 21 alert.addAction( 22 UIAlertAction( 23 title: "追加", 24 style: .default, 25 handler: { [self](action) -> Void in 26 alertStr = (alert.textFields?.first?.text!)! 27 28 let realm = try! Realm() 29 30 let addData = Model() 31 addData.name = self.alertStr 32 addData.id = String(UUID().uuidString) 33 addData.check = false 34 35 36 // MARK: Realm 37 if alertStr != "" { 38 39 switch self.usdf.string(forKey: "VC") { 40 case "VC1": 41 print("VC1") 42 43 try! realm.write { 44 realm.add(addData) 45 print("Realm_add_success_vc1") 46 47                 // この部分で次に記載するVCの関数を呼び出し、TableViewを再読み込みしようとしています 48 let VC1 = TableViewController1() 49 VC1.TVC1reload() 50 51 52 } 53 54 case "VC2": 55 <中略> 56 case "VC3": 57 <中略> 58 case "VC4": 59 <中略> 60 default: 61 print("none") 62 } 63 64 } else { 65 <中略> 66 } 67 68 69 70 }) 71 ) 72 73 //キャンセルボタン 74 alert.addAction( 75 UIAlertAction( 76 title: "キャンセル", 77 style: .cancel, 78 handler: {(action) -> Void in 79 80 }) 81 ) 82 83 //アラートを表示 84 self.present( 85 alert, 86 animated: true, 87 completion: { 88 print("アラートを表示") 89 }) 90 91 92 } 93 94 95 func topViewController(controller: UIViewController?) -> UIViewController? { 96 if let tabController = controller as? UITabBarController { 97 if let selected = tabController.selectedViewController { 98 return topViewController(controller: selected) 99 } 100 } 101 102 if let navigationController = controller as? UINavigationController { 103 return topViewController(controller: navigationController.visibleViewController) 104 } 105 106 if let presented = controller?.presentedViewController { 107 return topViewController(controller: presented) 108 } 109 110 return controller 111 } 112 113 114 115 override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { 116 //管理されるViewControllerを返す処理 117 let VC1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "1") 118 let VC2 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "2") 119 let VC3 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "3") 120 let VC4 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "4") 121 let childViewControllers:[UIViewController] = [VC1, VC2, VC3, VC4] 122 return childViewControllers 123 } 124

Swift

1------------------------------------------------------------------------- 2TableViewController1.swift】(上のStoryboardのキャプチャでは、1の部分になります) 3------------------------------------------------------------------------- 4 5 6// TagTitle 7 var itemInfo: IndicatorInfo = "食料品" 8 9 let realm = try! Realm() 10 11 let usdf = UserDefaults.standard 12 13 var array = [String]() 14 var checkarray = [Bool]() 15 16 override func viewDidLoad() { 17 super.viewDidLoad() 18 19 let results = realm.objects(Model.self) 20 print(results) 21 22 let count = results.count 23 if (count == 0) { 24 // データが0個 25 print("データなし") 26 } else { 27 // データが1個以上 28 for results in results { 29 array.append(results.name) 30 } 31 } 32 33 tableView.dataSource = self 34 tableView.delegate = self 35 36 <中略(セルのカラー設定)> 37 38 } 39 40 override func viewWillAppear(_ animated: Bool) { 41 42 // どこのVCかを判定できるようにする 43 usdf.set("VC1", forKey: "VC") 44 print("TVC1") 45 46 TVC1reload() 47 } 48 49 // 50 func TVC1reload() { 51 print("TVC1") 52 print("reload") 53 54 array.removeAll() 55 56 let results = realm.objects(Model.self) 57 let count = results.count 58 if (count == 0) { 59 // データが0個 60 } else { 61 // データが1個以上 62 for results in results { 63 array.append(results.name) 64 } 65 } 66 self.tableView.reloadData() 67 68 ⭐️ この部分はtableView.reloadData()以外は動作しています。(printで確認済み) 69` 70 } 71 72 func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo { 73 return itemInfo 74 } 75 76 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 77 return array.count 78 } 79 80 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 81 82 let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 83 cell.textLabel?.text = array[indexPath.row] 84 85 return cell 86 } 87 88 89 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 90 print(array[indexPath.row]) 91 92 let cell = tableView.cellForRow(at:indexPath) 93 94 tableView.deselectRow(at: indexPath, animated: true) 95 96 if cell?.accessoryType == .checkmark { 97 cell?.accessoryType = .none 98 99 } else { 100 cell?.accessoryType = .checkmark 101 } 102 }

イメージ説明

###最後に
大変長々と書いてしまい、申し訳ございません。
些細なことでも構いませんので、ご指摘・アドバイスなどご教授いただければと思います。よろしくお願い致します。

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

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

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

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

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

guest

回答3

0

自己解決

機能面、UI面を考慮し、XLPagerTabStripの使用を中止してUITabbarViewControllerに変更することとしました。

投稿2021/02/02 12:28

rea_sna

総合スコア32

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

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

0

XLPagerTabStripの View Controller に置かれている Button からほかの View Controller を操作するのであれば、次の方法が簡単かもしれません。

self.currentIndex には、現在表示している View Controller の Index が入っているので、self.viewControllers[] と併用することがも実現できます。

Swift

1import UIKit 2import XLPagerTabStrip 3 4class ViewController: ButtonBarPagerTabStripViewController { 5 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 } 9 10 override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { 11 12 let table1 = AnotherViewController() 13 table1.noteBookName = "book1" 14 15 let table2 = AnotherViewController() 16 table2.noteBookName = "book2" 17 18 return [table1, table2] 19 } 20 21 @IBAction func addTab(_ sender: Any) { 22 // currentIndex で現在表示されている View Controller の index がとれる 23 print(self.currentIndex) 24 25 // viewControllers[] には、タブで表示する ViewController が入っている 26 // 目的のインスタンスを取得する 27 let currentVC = self.viewControllers[self.currentIndex] as! AnotherViewController 28 29 // データを追加し、reloadData() する 30 currentVC.data.append(Int.random(in: 100...999).description) 31 currentVC.tableView.reloadData() 32 } 33} 34 35class AnotherViewController: UIViewController, UITableViewDataSource, IndicatorInfoProvider { 36 var data = ["First Item"] 37 var noteBookName: IndicatorInfo = "" 38 39 lazy var tableView: UITableView = { 40 let tv = UITableView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)) 41 tv.register(UITableViewCell.self, forCellReuseIdentifier: "cell") 42 tv.dataSource = self 43 return tv 44 }() 45 46 override func viewDidLoad() { 47 super.viewDidLoad() 48 49 view.addSubview(tableView) 50 } 51 52 func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo { 53 return noteBookName 54 } 55 56 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 57 return data.count 58 } 59 60 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 61 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 62 cell.textLabel?.text = data[indexPath.row] 63 64 return cell 65 } 66}

投稿2021/01/31 02:13

TsukubaDepot

総合スコア5086

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

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

rea_sna

2021/01/31 02:26

ご回答ありがとうございます。早速試してみます。
guest

0

swift

1let VC1 = TableViewController1() 2VC1.TVC1reload()

これだと、新しいインスタンスになるので、更新することができません。

なんらかの方法で、TableViewController1のインスタンスを渡す必要があります。

4つのViewController全てにテーブルの更新が必要なのであれば、私なら以下のようにします(あくまで例です)。

swift

1protocol ShppingListProtocol 2{ 3 func reload() 4} 5 6extension TableViewController1: ShppingListProtocol { 7 func reload() { 8 // TVC1reloadの実装 9 } 10} 11 12 13extension TableViewController2: ShppingListProtocol { 14 func reload() { 15 // TVC2reloadの実装 16 } 17} 18 19。。。

AppDelegateとかに現在表示中のShppingListProtocolインスタンスを設定し、DBに書き込んだら、そのインスタンス経由でreloadを呼び出す

投稿2021/01/30 15:54

t_obara

総合スコア5488

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問