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

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

ただいまの
回答率

88.78%

UISearchBarを使った検索実装が上手く機能しない Swift5

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 337

前提・実現したいこと

SearchBarでユーザー名を入れて該当する名前を絞り込みたい。

チャットアプリにユーザリストページを作り,ログイン済みのユーザーをTableViewに反映、そこにUISearchBar検索機能を実装しました。
ユーザーの名前をSearchBarに入れて絞り込みたいのですが、どうしても上手く絞り込みができず困り果てています。。。。
何卒よろしく御願い致します!

発生している問題・エラーメッセージ

SearchBarに名前を入れても、該当する名前に全く一致のしない名前が表示されます。
データベースから問題はなく呼び出しができていますが、class違いに振り分けられた配列の型に問題があるのか、filterやcontainsを使用したコードの定義に問題があるのかが分かりません。

該当のソースコード

import Foundation
import Firebase

struct UserForChat{
let email: String
let userName : String
let profileImage : String
let postDate : Timestamp
var uid : String?

init(dic:[String:Any]){

self.email = dic["email"] as? String ?? ""
self.userName = dic["userName"] as? String ?? ""
self.profileImage = dic["profileImage"] as? String ?? ""
self.postDate = dic["postDate"] as? Timestamp ?? Timestamp()

}
}

該当のソースコード

import UIKit
import Firebase

class UserListViewController:UIViewController{
//上記に定義したClassの配列
private var userForChat = [UserForChat]()
//検索に該当されたユーザー名が入る配列
private var searchResult = [Any]()
private var selectedUser : UserForChat?
private let cellId = "cell"
let db = Firestore.firestore()
let searchBar = UISearchBar()

@IBOutlet weak var userListTableView: UITableView!
@IBOutlet weak var startChatButton: UIButton!

override func viewDidLoad() {
super.viewDidLoad()

searchBar.delegate = self
searchResult = userForChat
setUp()
fetchUserInfoFromFirebase()
}

func setUp(){
userListTableView.tableFooterView = UIView()
userListTableView.delegate = self
userListTableView.dataSource = self
startChatButton.isEnabled = false
startChatButton.addTarget(self, action: #selector(tappedChatStartButton), for: .touchUpInside)
}

@objc func tappedChatStartButton(){
guard let uid = Auth.auth().currentUser?.uid else { return }
guard let partnerUid = self.selectedUser?.uid else { return }
let members = [uid,partnerUid]

let docData = [
"members":members,
"latestMessageId":"",
"postDate":Timestamp()
] as [String : Any]

db.collection("chatRooms").addDocument(data: docData){ (error) in
if let error = error{
print("ChatRoomの情報保存に失敗しました")
return
}
self.dismiss(animated: true, completion: nil)
}
}

func fetchUserInfoFromFirebase(){

db.collection("users").getDocuments { (snapshots, error) in
if let error = error{
print("FireStoreからの情報取得に失敗しました。")
return
}
self.userForChat.removeAll()
snapshots?.documents.forEach({ (snapshot) in
let dic = snapshot.data()
var user = UserForChat.init(dic: dic)
user.uid = snapshot.documentID

guard let uid = Auth.auth().currentUser?.uid else { return }
if uid == snapshot.documentID{
return
}
self.userForChat.append(user)
self.userListTableView.reloadData()
})
}
}
}
// MARK: - Search Bar Delegate Methods
extension UserListViewController:UISearchBarDelegate{

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
view.endEditing(true)
searchItems(searchText: searchBar.text! as String)
}

func searchItems(searchText: String) {
//
if searchText != "" {
searchResult = userForChat.filter { item in
item.userName.contains(searchText)
}
}else{
searchResult = userForChat
}
userListTableView.reloadData()
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchItems(searchText: searchText)
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.text = ""
view.endEditing(true)
searchResult = userForChat
userListTableView.reloadData()
}
}

//MARK: - UITableViewDelegate,UITableViewDataSource
extension UserListViewController:UITableViewDelegate,UITableViewDataSource{

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return ""
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
searchBar.placeholder = "Chatの相手を検索"
searchBar.showsCancelButton = true
searchBar.enablesReturnKeyAutomatically = false
return searchBar
}

func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchResult.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = userListTableView.dequeueReusableCell(withIdentifier: cellId, for:indexPath) as! UserListTableViewCell
cell.user = userForChat[indexPath.row]
return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
startChatButton.isEnabled = true
let user = userForChat[indexPath.row]
self.selectedUser = user
}

}

試したこと

上記以外に配列の定義を変えてみたり、filter、contains周りのコードを変更してみましたが、Value of type 'UserForChat' has no member 'contains'などのエラーになるなど。全く前に進めません。。。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hoshi-takanori

    2020/05/21 18:44

    cellForRowAt や didSelectRowAt でも userForChat ではなく searchResult を使うべきでは。
    (そして、searchResult の型も [UserForChat] にすべきでしょう。)

    キャンセル

  • SadajiroOkuno

    2020/05/21 18:56

    hoshiさん, 早急の御回答本当にありがとうございます!!!
    解決致しました!!!
    何日も進めなかったので。。。本当に助かりました。
    そしてもっと勉強致します。
    本当ありがとうございます!

    キャンセル

回答 1

check解決した方法

0

hoshi-takanoriさんに御回答いただきました。 ありがとうございました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る