2017-03-31 11 views
0

ユーザーが検索バーにすべての文字を入力するときに、ユーザー名でテーブルビューを更新する検索バーがあります。ユーザーが検索バーのすべての文字を削除(バックスペース)すると、つまり検索バーが空の場合、テーブルビューにユーザー名を表示せずに空にします。iOS - UISearchBarの動的検索結果が速く入力されたときに機能しない

私はユーザー名(Parse backend)を検索する準機能のUISearchbarを持っています。文字を検索バーに文字でゆっくり入力するとうまく動作します。

しかし、すぐに入力すると、検索結果が少しオフになります。以前に入力した文字のユーザー名が表示されます。たとえば:「nik」と入力すると、すぐに「ni」というユーザー名が表示されます。また、検索バーに文字がなくなるまですばやくバックスペースをとると、特定のユーザー名が表示されます。

また、文字をゆっくり入力するとうまく動作しますが、あまり効率的でないように感じます。私はあらゆる種類のことを試みましたが、これまでのところうまくいったことはありません。以下の関連コードを追加しました。詳細情報が必要な場合はお知らせください。

// called when keyboard search button pressed 
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { 

    let searchString = searchBar.text; 

    if (searchString != "") { 
     //do load users 
     loadUsers(searchText: searchString!); 
     print("called from searchBarSearchButtonClicked"); 
    } 

} 

// called when cancel button pressed 
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { 

    searchBar.text = ""; 

    //hide tableview maybe?! 
    //searchTableView.isHidden = true; 

} 

func updateSearchResults(for searchController: UISearchController) { 
    let searchString: String = (searchController.searchBar.text)!; 


    /*if (searchString == "" && !searchActive) { 
     searchResults.removeAll(keepingCapacity: false); 
     searchTableView.reloadData(); 
     print("test"); 
    }*/ 

    if (searchString != "" && !self.searchActive) { 
     loadUsers(searchText: searchString); 
     print("called from updateResults"); 
    } 

    if (searchString == "") { 
     searchResults.removeAll(keepingCapacity: false); 
     searchTableView.reloadData(); 
     print("test"); 
    } 
} 


func loadUsers(searchText: String) { 

    if(searchText != "") { 


     let usernameQuery = PFUser.query(); 
     //usernameQuery?.whereKey("username", equalTo: searchText); 
     usernameQuery?.whereKey("username", contains: searchText.lowercased()); 


     let fbUsername = PFUser.query(); 
     fbUsername?.whereKey("username", contains: searchText); 


     let firstnameQuery = PFUser.query(); 
     //firstnameQuery?.whereKey("last_name", equalTo: searchText) 
     firstnameQuery?.whereKey("last_name", contains: searchText); 


     let lastnameQuery = PFUser.query(); 
     //lastnameQuery?.whereKey("first_name", equalTo: searchText); 
     lastnameQuery?.whereKey("first_name", contains: searchText); 


     let query = PFQuery.orQuery(withSubqueries: [usernameQuery!,fbUsername!, firstnameQuery!, lastnameQuery!]); 

     searchActive = true; 

     query.findObjectsInBackground { (objects, error) in 

      if error != nil { 

       print("There was an error getting userlist"); 

      } 

      else { 

       if let object = objects { 

        self.searchResults.removeAll(keepingCapacity: false); 

        for object in objects! { 

         let user = object.object(forKey: "username") as! String; 
         self.searchResults.append(user); 

        } 

        //self.searchTableView.reloadData(); 


        DispatchQueue.main.async { 

        self.searchTableView.reloadData(); 

        //self.userSearchController.searchBar.resignFirstResponder(); 

        } 

       } 

      } 

      self.searchActive = false; 

     } 
    } 

} 


override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 


public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

    if(userSearchController.isActive) { 

     print(searchResults.count); 
     return searchResults.count; 

    } 

    return 0; 
} 


public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath); 

    if(self.userSearchController.isActive && searchResults.count > indexPath.row) { 

     print(searchResults[indexPath.row]); 
     cell.textLabel?.text = searchResults[indexPath.row]; 

    } 

    return cell; 

} 




/* 
public func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool { 
    return true; 
} 

public func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool { 
    return true; 
} 



func searchBarTextDidEndEditing(_ searchBar: UISearchBar) { 

     //loadUsers(searchText: (searchBar.text)!); 
} */ 


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

    if (searchBar.text != "") { 
     NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(loadUsers(searchText:)), object: searchBar.text! as String); 


     perform(#selector(loadUsers(searchText:)), with: searchBar.text! as String, afterDelay: 0.50); 


     print("called from textDidChange"); 

    } 
    if (searchBar.text == "") { 

     searchResults.removeAll(keepingCapacity: false); 
     searchTableView.reloadData(); 
     print("test2"); 
    } 

} 

答えて

0

タイマーを使用してこの問題を解決しました。以下のコードは、関数を呼び出す前に1秒間待機しています。その1秒間にテキストの変更が発生した場合、前のスケジュールされたタイマーが無効になり、2番目のタイマーだけが変更されます。これを確認するには、検索テキストを関数に印刷します。

var timer: Timer? 

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 
     timer?.invalidate() //cancels out previous Timers 
     timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(myFunctionThatDoesServerSearch), userInfo: nil, repeats: false) 
    } 
関連する問題