UISearchController 使用谓词 [Swift] 从 UISearchBar 搜索数据

UISearchController to search data from UISearchBar using predicate [Swift]

唯一错误的是,当我 运行 我的代码点击搜索栏并点击一个字母时,我没有在结果中显示正确的数据 table.

我对 swift 语言还是很陌生,我认为这与谓词有关,但我不确定。

{

    import UIKit

    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UISearchResultsUpdating {

    @IBOutlet weak var tableview: UITableView!

    //Setting variable to array
    var dataArray : [MedicalInfo] = []
    var filteredData = [NSObject]()

    var resultSearchController = UISearchController()


    override func viewDidLoad() {
        super.viewDidLoad()

        //Adding medical info
        var medical1 : MedicalInfo = MedicalInfo()
        medical1.name = "Abdominal Pain"
        medical1.symptoms = "Seek immediate medical care if you have pain and tenderness to the touch in the lower right abdomen with fever and/or vomiting. These may be signs of appendicitis.  You are pregnant and have abdominal pain or vaginal bleeding. This may be a sign of an ectopic pregnancy or miscarriage."
        medical1.steps = "1. Treat Symptoms.  For heartburn from gastroesophageal reflux disease (GERD), take an over-the-counter antacid or acid reducer.  For constipation, take a mild stool softener or laxative.  For pain, take acetaminophen (Aspirin Free Anacin, Liquiprin, Panadol, Tylenol). Avoid NSAIDs such as aspirin, ibuprofen (Advil, Midol, Motrin), or naproxen (Naprosyn, Aleve, Anaprox, Naprelan), because they can cause stomach irritation or bleeding.  2. When to call a doctor.  Has severe abdominal pain or pain that lasts several days.  Has nausea, fever, or inability to keep food down for several days.  Has bloody stools.  Has painful urination.  Has blood in the urine.  Cannot pass stools, especially if also vomiting.  Has difficulty breathing.  Had an injury to the abdomen in the days before the pain started.  Has heartburn that isn't relieved by over-the-counter drugs or last longer than two weeks.  3. When to call 911.  Call 911 if the person: Vomits blood.  Has severe difficulty breathing."


        var medical2 : MedicalInfo = MedicalInfo()
        medical2.name = "Abdominal Pain in Children"
        medical2.symptoms = "Call 911 if the child is not moving or is too weak to stand."
        medical2.steps = "1. Have your child rest.  Avoid activity, especially after eating.  2. Treat symptoms.  Provide clear fluids to sip, such as water, broth, or fruit juice diluted with water.  Serve bland foods, such as saltine crackers, plain bread, dry toast, rice, gelatin, or applesauce.  Avoid spicy or greasy foods and caffeinated or carbonated drinks until 48 hours after all symptoms have gone away.  Encourage the child to have a bowel movement.  Ask your child’s doctor before giving any medicine for abdominal pain. Drugs can mask or worsen the pain.  3.  When to call 911.  Call your child’s doctor immediately if your child has any of the following: Persistent pain on the right side of the abdomen, which could be an appendicitis.  Pain confined to one part of the abdomen.  Severe or rapidly worsening abdominal pain or pain that doesn’t go away within 24 hours.  Pain or tenderness when you press on the belly.  A swollen abdomen or an abdomen that is rigid to the touch.  Pain in the groin, or pain or swelling in a testicle.  Unexplained fever.  Lots of vomiting or diarrhea.  Bleeding from the rectum.  Blood in the stool or vomit.  A recent abdominal injury."


        var medical3 : MedicalInfo = MedicalInfo()
        medical3.name = "Alcohol Intoxication"
        medical3.symptoms = "Call 911 if the person has these symptoms of alcohol poisoning.  Mental confusion or unconsciousness.  Repeated vomiting.  Seizures.  Slow or irregular breathing.  Low body temperature.  Pale, clammy, or bluish skin"
        medical3.steps = "1. Stop further drinking.  Leave the place where the alcohol is, or put the alcohol away.  Coffee, cold showers, and other traditional remedies don't work.  2. Keep the person safe.  Never allow someone to drive when they are drunk.  Keep the person away from machinery, bicycles, skateboards, swimming pools, and other hazards.  Watch for signs of alcohol poisoning."


        var medical4 : MedicalInfo = MedicalInfo()
        medical4.name = "Allergic Reaction"
        medical4.symptoms = "Call 911 now if the person has had severe reactions in the past or has any of these symptoms: Difficulty breathing or wheezing.  Tightness in the throat or a feeling that the airways are closing.  Hoarseness or trouble speaking.  Swollen lips, tongue, or throat.  Nausea, abdominal pain, or vomiting.  Fast heartbeat or pulse.  Anxiety or dizziness.  Loss of consciousness.  Other symptoms of a severe allergic reaction (anaphylaxis)."
        medical4.steps = "1. Treat symptoms.  For mild allergy symptoms, such as hay fever or hives, give an over-the-counter (OTC) antihistamine.  For stuffy nose, give an OTC decongestant.  For itchy, watery eyes, use OTC allergy eye drops.  For itchy allergic rash, apply cold compresses and an OTC hydrocortisone cream.  2. Follow up.  Watch for worsening symptoms, including signs of anaphylaxis."


        var medical5 : MedicalInfo = MedicalInfo()
        medical5.name = "Amputation"
        medical5.symptoms = "Loss of limb."
        medical5.steps = "1. Call 911.  2. Stop the bleeding.  Wash your hands with soap and water, if possible.  Have the injured person lie down, if possible. Don’t reposition the person if you suspect a head, neck, back, or leg injury.  Elevate the injured area.  Apply steady, direct pressure to the wound for 15 minutes. You can do this up to three times. If there’s an object in the wound, apply pressure around it, not directly over it.  If blood soaks through, apply another covering over the first one. Don’t take the first one off.  Use a tourniquet or compression bandage only if bleeding is severe and not stopped with direct pressure.  3. Check for and treat shock.  With the person still lying flat, raise feet 12 inches.  Cover with coat or blanket.  Calm the person as much as possible until medical help arrives.  4. Clean and protect wound.  Wrap or cover the injured area with sterile dressing or clean cloth.  5. Save amputated part.  In some cases, the amputated part can be reattached.  If possible, rinse with clean water to remove dirt or debris. Do not use soap or scrub.  Place in a clean, plastic bag.  Pack the bag in ice. Take it with you to the hospital."




        //Adding info to array
        dataArray.append(medical1)
        dataArray.append(medical2)
        dataArray.append(medical3)
        dataArray.append(medical4)
        dataArray.append(medical5)


        resultSearchController = UISearchController(searchResultsController: nil)
        resultSearchController.searchResultsUpdater = self
        resultSearchController.hidesNavigationBarDuringPresentation = false
        resultSearchController.dimsBackgroundDuringPresentation = false
        resultSearchController.searchBar.sizeToFit()
        tableview.tableHeaderView = resultSearchController.searchBar
        tableview.reloadData()

    }


    //Function to add number of rows in tableview
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        if resultSearchController.active
        {
            return filteredData.count
        }
        else
        {
            return dataArray.count
        }
    }


    //Function to add tableview row data
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        //Variable to reuse cell identifier called MyCell
        var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MyCell") as! UITableViewCell


        if resultSearchController.active
        {

        }
        else
        {
            let currentMedical : MedicalInfo = dataArray[indexPath.row]

            //Changing font and adding text to rows
            cell.textLabel!.font = UIFont(name: "Georgia", size: 13)
            cell.textLabel!.text = currentMedical.name
        }

        return cell
    }


    func updateSearchResultsForSearchController(searchController: UISearchController) {

        filteredData.removeAll(keepCapacity: false)

        let searchPredicate = NSPredicate(format: "SELF.name CONTAINS[c] %@", searchController.searchBar.text)

        var array = (dataArray as NSArray).filteredArrayUsingPredicate(searchPredicate)

        filteredData = array as! [NSObject]

        tableview.reloadData()

    }

}

用以下方法替换您的 cellForRowAtIndexPath:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        //Variable to reuse cell identifier called MyCell
        var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MyCell") as! UITableViewCell


        if resultSearchController.active
        {
            cell.textLabel!.text = filteredData[indexPath.row]
        }
        else
        {
            let currentMedical : MedicalInfo = dataArray[indexPath.row]

            //Changing font and adding text to rows
            cell.textLabel!.font = UIFont(name: "Georgia", size: 13)
            cell.textLabel!.text = currentMedical.name
        }

        return cell
    }

Edited Answer:

将您的变量 filterData 更改为以下内容:

var filteredData = [String]()

我终于明白了。我必须像其他数组一样将 filteredData 更改为 MedicalInfo 对象。然后将文本标签更改为此。感谢所有帮助过的人。

   //Function to add tableview row data
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    //Variable to reuse cell identifier called MyCell
    var cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MyCell") as! UITableViewCell

    //If search controller is active
    if resultSearchController.active
    {
        //Setting search results
        let currentMedical : MedicalInfo = filteredData[indexPath.row]
        //Setting the text to the tableview results
        cell.textLabel!.text = currentMedical.name
    }
    else
    {
        let currentMedical : MedicalInfo = dataArray[indexPath.row]
        //Changing font and adding text to rows
        cell.textLabel!.font = UIFont(name: "Georgia", size: 13)
        cell.textLabel!.text = currentMedical.name
    }
    return cell
}