Ben Sullivan
Ben Sullivan

Reputation: 2154

Filtering arrays for use with UISearchBar

I have a table view which displays a user's Name, Company Name and Photo (PFFile). Each tableView row I have has all of this information in it.

I am using UISearchBarDelegate and IB to implement a search function to filter by the user's Name. It is finding the correct user but I have not been able to also update the company photo.

How do I filter the other arrays? The items I need from the arrays will be at the same index as the ones taken from the user's Name array.

EDIT: I am trying a different data structure and am receiving array index out of range, updated code below:

var filterArray = [User]()  //<-- globally declared
var userArray = [User]() //< Global


class User {

var name: String?
var company: String?

init (name: String?, company: String?) {

    self.name = name
    self.company = company
    }
}
//In a class which populates the search arrays
for object in unwrappedSucceeded {

   let username = object.valueForKey("username") as! String
   let companyName = object.valueForKey("companyName") as! String
   let user = User(name: username, company: companyName)

    userArray.append(user)
}

//tableViewController

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

    filterArray.removeAll(keepCapacity: false)

    if searchText.characters.count != 0 {
        isSearch = true

        self.search(searchText)

    } else {
        isSearch = false
    }
}


func search(text: String) -> Void {

    filterArray = userArray.filter({$0.name == text})

}
//In cellForRowAtIndexPath
            cell.usernameCell.text = filterArray[indexPath.row].name //ARRAY INDEX OUT OF RANGE

Upvotes: 1

Views: 2098

Answers (2)

Lamour
Lamour

Reputation: 3030

Like I said you strongly recommend to group each user's info into one big container, therefore we could use array of struct or class, then it comes easier to filter.

schematic for the container:

struct Container
{
  var username:String?
  var companyName:String?
  var photo:UIImage?
}

your main array will be : var arrayofData = [Container]()

Now when you are query your objects from parse, inside of your query function

// after you called the findObjectsWithBackgroundBlock()
// let's assume you check for error and if the [PFObject] is empty or not 

 for one in objectsFromParse
 {
  let photoToget = one["Photo"] as! PFFile
 // next step should be to get the image data right :) 
 {
    // let's assume that is the block when get the image data right:)
    // check your data and assign it to some UIImage
     // then 
     let userRepresentation = Container()  //<-- we are creating a single object representation for each user 

     let username = one["username"] as! String    //<--data we got from Parse
     let companyName = one["companyName"] as! String
     let userImage = //the UIImage which contains the data 

     userRepresentation.username = username
     userRepresentation.companyName = companyName
     userRepresentation.photo = userImage

  // then we append 
    arrayOfData.append(userRepresentation)
 }
}

Now we have all data into our array, so let's filter by username and also I hope you configure your tableView so when you have data from filter or regular array.

  var filterArray = [Container]()  //<-- globally declared

  func search(text: String) -> Void
 {
    filterArray = arrayOfData.filter(){ (Container) -> Bool in
       let range = Container.name!.rangeOfString(text,   options:NSStringCompareOptions.CaseInsensitiveSearch) return range != nil }
       // then you are good to go 
 }

Upvotes: 2

user3441734
user3441734

Reputation: 17534

let arr1 = [10,20,40]
let e1 = arr1.enumerate()
let arr2 = ["a","b","c"]
let f1 = e1.filter { $0.element % 20 == 0 }
let f2 = arr2.enumerate().filter { j, _ in
    f1.contains { i, _ in
        i == j
    }
}

print(f1.map{$0.element}, f2.map{$0.element})
// [20, 40] ["b", "c"]

now you have both arrays "filtered". the best, what you can do is redesigning your data model!

Upvotes: 0

Related Questions