2017-03-31 4 views
0

사용자가 검색 창에 입력 할 때마다 사용자 이름으로 tableview를 업데이트하는 검색 막대가 필요합니다. 사용자가 검색 창에있는 모든 문자를 삭제 (백 스페이스) 할 때 (예 : 검색 창이 비어있는 경우) 테이블 뷰에 사용자 이름이 표시되지 않고 비어 있어야합니다.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 초에 발생하면 이전 예약 된 타이머가 무효화되고 두 번째 타이머 만 수행됩니다. 함수에서 검색 텍스트를 인쇄하여이를 확인할 수 있습니다.

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) 
    }