web-dev-qa-db-ja.com

UITextFieldをSwiftのUISearchBarのように動作させる方法は?

こんにちは皆さん私はSwiftでUITableViewとUISearchBarを使用して新しいアプリに取り組んでおり、それはすでに正常に機能しています。しかし、最終プロジェクトには完全にカスタマイズされた検索バーが必要なので、UITextFieldに移動する必要がありました。カスタマイズの可能性があるため、入力アウトレット。

問題は、UITextFieldがUISearchBarのように動作するようにコーディングする方法がわからないことです。 UITextField入力をフィルタリングし、UISearchBarDelegateメソッドで文字列を使用できるようにする方法がわかりません。

だから誰かがこれで私を助けることができますか?

編集:私はダニエルの助けに従ってこのコードを思いついたが、それは「nil」を返し、機能しない。

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate {

@IBOutlet weak var txtSearchBar: UITextField!
var searchTxt = ""
let prods = ["água", "terra", "ar", "fogo"]
var searchResults:[String] = []

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    txtSearchBar.delegate = self
}


func textFieldDidEndEditing(textField: UITextField) {
    searchTxt = textField.text
    println(searchTxt)
    searchResults = prods.filter({(produtos:String) -> Bool in

        let nameMatch = produtos.rangeOfString(self.searchTxt, options: NSStringCompareOptions.CaseInsensitiveSearch)

        println(nameMatch)
        return nameMatch != nil})
}

私の入力は文字「ar」でしたが、配列のオブジェクトの1つが「ar」であるために返されるべきではないのに「nil」を返しました。

10
Marco Almeida

@Daniel Tの助けを借りて、私は次のコードで問題を解決することができました。

func textFieldShouldReturn(textField: UITextField) -> Bool {
    isFiltered = true
    searchResults = prods.filter({(coisas:String) -> Bool in
        let stringMatch = coisas.rangeOfString(textField.text)
        return stringMatch != nil

    })
    println(searchResults.description)
    textField.resignFirstResponder()
    table.reloadData()
    return true
}

ありがとう@DanielT。

0
Marco Almeida

Uitextfieldオブジェクトを作成します。

@IBOutlet var SearchTxt: UITextField!
var search:String=""

@IBOutlet var ListTable: UITableView!
var AllData:Array<Dictionary<String,String>> = []
var SearchData:Array<Dictionary<String,String>> = []

Viewdidload:

override func viewDidLoad()
{
    super.viewDidLoad()

    AllData = [["pic":"list0.jpg", "name":"Angel Mark", "msg":"Hi there, I would like read your...", "time":"just now", "unread":"12"],
               ["pic":"list1.jpg", "name":"John Doe", "msg":"I would prefer reading on night...", "time":"56 second ago", "unread":"2"],
               ["pic":"list2.jpg", "name":"Krishta Hide", "msg":"Okey Great..!", "time":"2m ago", "unread":"0"],
               ["pic":"list3.jpg", "name":"Keithy Pamela", "msg":"I am waiting there", "time":"5h ago", "unread":"0"]
               ]

    SearchData=AllData
}

テキストフィールドデリゲートメソッドで検索:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
    if string.isEmpty
    {
        search = String(search.characters.dropLast())
    }
    else
    {
        search=textField.text!+string
    }

    print(search)
    let predicate=NSPredicate(format: "SELF.name CONTAINS[cd] %@", search)
    let arr=(AllData as NSArray).filtered(using: predicate)

    if arr.count > 0
    {
        SearchData.removeAll(keepingCapacity: true)
        SearchData=arr as! Array<Dictionary<String,String>>
    }
    else
    {
        SearchData=AllData
    }
    ListTable.reloadData()
    return true
}

テーブルビューでの検索データ表示:

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
    let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! ListCell

    var Data:Dictionary<String,String> = SearchData[indexPath.row]

    cell.Pic.image=UIImage(named: Data["pic"]!)
    cell.Name.text = Data["name"]
    cell.Msg.text = Data["msg"]
    cell.Time.text = Data["time"]

    cell.selectionStyle = .none
    return cell
}
10
Jayesh Miruliya

あなたの主な質問は、UISearchBarのように機能するクラスを実装する方法を尋ねているようです。それは大きな仕事になるでしょう!

ただし、メモでは、検索ボタンがタップされた場合の対応方法を尋ねるだけです。

IBActionと2番目の配列をViewControllerに追加します。 2番目の配列を「foundItems」のようなものと呼びます。 IBActionを検索ボタンに接続します。アクションが呼び出されたら、テキストフィールドからテキストを読み取り、そのテキストに基づいてアイテムをフィルタリングします。フィルタに準拠するアイテムをfoundItems配列に配置し、テーブルビューでreloadData()を呼び出します。

テーブルビューのデータソースメソッドで、foundItemsがnilでないかどうかを確認します。そうでない場合は、メインのアイテム配列の代わりにそれらを表示します。

また、何らかのキャンセルボタンが必要になります。そのボタンのアクションで、foundItems配列を削除し、テーブルビューでreloadData()を呼び出します。

3
Daniel T.

Xcode 9.2/Swift 4--作業コード

 @IBOutlet var tfSearchWorker: UITextField!
 @IBOutlet var tblView: UITableView!

 var AllData :Array<Dictionary<String,String>> = []
 var SearchedData:Array<Dictionary<String,String>> = []

@ViewDidLoad

 AllData = [["pic":"list0.jpg", "name":"Angel Mark", "msg":"Hi there, I would like read your...", "time":"just now", "unread":"12"],
           ["pic":"list1.jpg", "name":"John Doe", "msg":"I would prefer reading on night...", "time":"56 second ago", "unread":"2"],
           ["pic":"list2.jpg", "name":"Krishta Hide", "msg":"Okey Great..!", "time":"2m ago", "unread":"0"],
           ["pic":"list3.jpg", "name":"Keithy Pamela", "msg":"I am waiting there", "time":"5h ago", "unread":"0"]
           ]

self.SearchedData = self.AllData
self.tfSearchWorker.addTarget(self, action: #selector(searchWorkersAsPerText(_ :)), for: .editingChanged)

@関数

@objc func searchWorkersAsPerText(_ textfield:UITextField) {
    self.SearchedData.removeAll()
    if textfield.text?.count != 0 {
        for dicData in self.AllData {
            let isMachingWorker : NSString = (dicData.name!) as NSString
            let range = isMachingWorker.lowercased.range(of: textfield.text!, options: NSString.CompareOptions.caseInsensitive, range: nil,   locale: nil)
            if range != nil {
                SearchedData.append(dicData)
            }
        }
    } else {
        self.SearchedData = self.AllData
    }
    self.tblView.reloadData()
}

@UITableView

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

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
     let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell") as! ListCell

     var Data:Dictionary<String,String> = SearchedData[indexPath.row]

     cell.Pic.image=UIImage(named: Data["pic"]!)
     cell.Name.text = Data["name"]
     cell.Msg.text = Data["msg"]
     cell.Time.text = Data["time"]

     cell.selectionStyle = .none
     return cell
}
3
Krunal Patel