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

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

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

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

Swift

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

Q&A

解決済

1回答

559閲覧

NCMBで取得したユーザー情報が表示されない

nekokichi

総合スコア54

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/12/27 03:46

編集2018/12/27 04:17

NiftyCloudを使ってSNSのサンプルを作っています。

今実現したいのは、インスタのような
・アイコン
・ユーザー名
がCellで表示されたタイムライン画面です。

イメージ説明

ViewDidLoad内でユーザー情報の取得はできるのですが、
・tableViewを更新してるのに表示されない
・データ処理の順番がおかしい
という問題に直面しています。

イメージ説明

①tableViewを更新してるのに表示されない
ViewDidLoad内でNCMBからユーザー情報を取得し、そのあとにtableView.reloadDataを実装しているので、普通ならcellForRowAtが呼ばれて、カスタムセル(Xib)内のImageViewとLabelにそれぞれ値が代入されるはずです。

しかし、ブレイクポイントをcellForRowAt内で設定しても、1つも通らないのです。

ViewDidLoad内ではtableView.reloadDataは実行されないのでしょうか?

②データ処理の順番がおかしい
下記のソースコードだと、

1,データ取得
2,"111"表示
3,データ数を表示

のはずが、

1,"111"表示
2,データ取得失敗?
3,データ数を表示
4,データ取得

という順番になってしまいます。

他の場所でloadUserは実行してないのに謎です。

どうかご協力願います。

Swift

1import UIKit 2import NCMB 3 4class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate { 5 6 //NCMBUser配列の宣言 7 var users = [NCMBUser]() 8 9 //検索バーの宣言 10 var searchBar: UISearchBar! 11 12 @IBOutlet weak var tableView: UITableView! 13 14 override func viewDidLoad() { 15 super.viewDidLoad() 16// 17// let upvc = storyboard?.instantiateViewController(withIdentifier: "userpageID") as! UserPageViewController 18// 19// let user = NCMBUser 20 21 //検索バーを設置 22 setSearchBar() 23 24 tableView.register(UINib(nibName: "TimeLineViewCell", bundle: Bundle.main), forCellReuseIdentifier: "timelinecell") 25 //tableViewのセルの高さを設定 26 tableView.estimatedRowHeight = 80 27 tableView.rowHeight = 80 28 tableView.tableFooterView = UIView() 29 30 loadUsers(searchText: nil) 31 print("111") 32 print(self.users) 33 tableView.reloadData() 34 35 } 36 37 override func viewWillAppear(_ animated: Bool) { 38 super.viewWillAppear(animated) 39 40 tableView.reloadData() 41 } 42 43 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 44 return self.users.count 45 } 46 47 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 48 let cell = tableView.dequeueReusableCell(withIdentifier: "timelinecell", for: indexPath) as! TimeLineViewCell 49 50 cell.iconImageView.layer.cornerRadius = cell.iconImageView.bounds.width / 2.0 51 cell.iconImageView.layer.masksToBounds = true 52 53 //ユーザー名を取得 54 if let _ = users[indexPath.row].userName { 55 56 cell.userName.text = "@" + users[indexPath.row].userName 57 } 58 //アイコン画像を取得 59 if let readData_icon = NCMBFile.file(withName: "icon " + users[indexPath.row].objectId, data: nil) as? NCMBFile { 60 print("icon") 61 readData_icon.getDataInBackground { (data, error) in 62 if error != nil { 63 print(error) 64 } else { 65 cell.iconImageView.image = UIImage(data: data!) 66 } 67 } 68 } 69 70 return cell 71 } 72 73 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 74 //DetailViewControllerのインスタンス 75 let DVC = storyboard?.instantiateViewController(withIdentifier: "godetail") as! DetailViewController 76 //選択したNCMBUserを渡す 77 DVC.user = users[indexPath.row] 78 tableView.deselectRow(at: indexPath, animated: true) 79 } 80 81 //メニューボタン 82 @IBAction func logout(_ sender: Any) { 83 let alert = UIAlertController(title: "メニュー", message: nil, preferredStyle: .alert) 84 let logoutAction = UIAlertAction(title: "ログアウト", style: .default) { (action) in 85 NCMBUser.logOutInBackground({ (error) in 86 if error != nil { 87 print("logout error") 88 } else { 89 self.syncronize() 90 } 91 }) 92 } 93 let deleteAction = UIAlertAction(title: "退会", style: .destructive) { (action) in 94 let user = NCMBUser.current() 95 user?.deleteInBackground({ (error) in 96 if error != nil { 97 print("delete error") 98 } else { 99 self.syncronize() 100 } 101 }) 102 } 103 let cancelAction = UIAlertAction(title: "キャンセル", style: .cancel) { (action) in 104 alert.dismiss(animated: true, completion: nil) 105 } 106 alert.addAction(logoutAction) 107 alert.addAction(deleteAction) 108 alert.addAction(cancelAction) 109 self.present(alert, animated: true, completion: nil) 110 } 111 112 //検索バーの設置 113 func setSearchBar() { 114 // NavigationBarにSearchBarをセット 115 if let navigationBarFrame = self.navigationController?.navigationBar.bounds { 116 //NavigationBarに適したサイズの検索バーを設置 117 let searchBar: UISearchBar = UISearchBar(frame: navigationBarFrame) 118 //デリゲート 119 searchBar.delegate = self 120 //プレースホルダー 121 searchBar.placeholder = "ユーザーを検索" 122 //検索バーのスタイル 123 searchBar.autocapitalizationType = UITextAutocapitalizationType.none 124 //NavigationTitleが置かれるView? 125 navigationItem.titleView = searchBar 126 //titleViewのサイズ 127 navigationItem.titleView?.frame = searchBar.frame 128 //NavigationBarにセット 129 self.searchBar = searchBar 130 } 131 } 132 133 //検索バーで入力する時 134 func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool { 135 searchBar.setShowsCancelButton(true, animated: true) 136 return true 137 } 138 139 //検索バーのキャンセルがタップされた時 140 func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { 141 loadUsers(searchText: nil) 142 searchBar.showsCancelButton = false 143 searchBar.resignFirstResponder() 144 } 145 146 //検索バーでEnterが押された時 147 func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { 148 loadUsers(searchText: searchBar.text) 149 } 150 151 //ユーザーを読み込む 152 func loadUsers(searchText: String?) { 153 let query = NCMBUser.query() 154 // 自分を除外 155 query?.whereKey("objectId", notEqualTo: false) 156 157 // 退会済みアカウントを除外 158 query?.whereKey("active", notEqualTo: false) 159 160 // 検索ワードがある場合 161 if let text = searchText { 162 query?.whereKey("userName", equalTo: text) 163 } 164 165 // 新着ユーザー50人だけ拾う 166 query?.limit = 50 167 // 降順にソート 168 query?.order(byDescending: "createDate") 169 170 query?.findObjectsInBackground({ (result, error) in 171 if error != nil { 172 print(error) 173 } else { 174 // 取得した新着50件のユーザーを格納 175 self.users = result as! [NCMBUser] 176 print(self.users.count) 177 print(self.users) 178 } 179 }) 180 181 } 182 183 //ログアウトする際の処理 184 func syncronize() { 185 //storyboardを宣言 186 let storyboard = UIStoryboard(name: "SignIN", bundle: Bundle.main) 187 let next = storyboard.instantiateViewController(withIdentifier: "signin") 188 next.modalTransitionStyle = .crossDissolve 189 self.present(next, animated: true, completion: nil) 190 //ログイン状態を解除 191 let ud = UserDefaults.standard 192 ud.set(false, forKey: "LoginStatus") 193 ud.synchronize() 194 } 195 196}
111 [] 2 [{ "FacebookURL" : "", "Profile" : "プロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィール", "mailAddress" : null, "mailAddressConfirm" : null, "createDate" : { "__type" : "Date", "iso" : "2018-12-26T08:33:43.652Z" }, "TwitterURL" : "", "ItemColor" : "gray", "authData" : null, "userName" : "bbbb", "Item" : [ [ "", "" ], [ "", "" ] ], "updateDate" : { "__type" : "Date", "iso" : "2018-12-26T08:46:27.967Z" }, "acl" : { "*" : { "write" : true, "read" : true } }, "objectId" : "OwcALHFIN84EKhF8", "InstagramURL" : "" }, { "FacebookURL" : "", "Profile" : "プロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィールプロフィール", "mailAddress" : null, "mailAddressConfirm" : null, "createDate" : { "__type" : "Date", "iso" : "2018-12-26T04:53:44.287Z" }, "TwitterURL" : "", "ItemColor" : "gray", "authData" : null, "userName" : "aaaa", "Item" : [ [ "", "" ], [ "", "" ] ], "updateDate" : { "__type" : "Date", "iso" : "2018-12-26T09:33:06.589Z" }, "acl" : { "*" : { "write" : true, "read" : true } }, "objectId" : "ER5JnK8Av4hyLQIp", "InstagramURL" : "" }]

※追記
ViewDidLoad下に下記を追加したら、

override func viewDidLoad() { super.viewDidLoad() // // let upvc = storyboard?.instantiateViewController(withIdentifier: "userpageID") as! UserPageViewController // // let user = NCMBUser //検索バーを設置 setSearchBar() tableView.register(UINib(nibName: "TimeLineViewCell", bundle: Bundle.main), forCellReuseIdentifier: "timelinecell") //tableViewのセルの高さを設定 tableView.estimatedRowHeight = 80 tableView.rowHeight = 80 tableView.tableFooterView = UIView() print("3") loadUsers(searchText: nil) print("1") tableView.reloadData() print("2") }

下記のように表示されてるので、tableView.reloadDataは通っているはずなのですが。

3 1 2 2 [{ "FacebookURL" : "",

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

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

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

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

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

fuzzball

2018/12/27 03:52

○○InBackgroundというのは非同期処理ではないのでしょうか?
nekokichi

2018/12/27 03:54

恐らく..そうだと思います。
fuzzball

2018/12/27 03:58

「"111"表示」以外の項目の、コードでの具体的な位置を書いて下さい。
fuzzball

2018/12/27 04:07

とりあえずですが、viewWillAppear で reloadData()するので、viewDidLoad の reloadData() は不要です。
nekokichi

2018/12/27 04:19

追記しました。
guest

回答1

0

ベストアンサー

データ取得完了前に、いくらreloadData()してもテーブルには何も表示されません。
データ取得完了後にreloadData()を呼んで下さい。

投稿2018/12/27 04:27

編集2018/12/27 04:27
fuzzball

総合スコア16731

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

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

nekokichi

2018/12/27 04:30

データ完了後はどこでしょうか? viewWillAppearの最後ですか?
fuzzball

2018/12/27 04:33

あなたが「データ取得」と書いているのはデータ完了後のことではないのですか?
nekokichi

2018/12/27 04:38

解決しました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問