Filtering TableView with array in array - ios

I have 2 methods:
class Sign {
let code: String
let name: String
let description: String
let picture: String
init(code: String, name: String, description: String, picture: String) {
self.code = code
self.name = name
self.description = description
self.picture = picture
}
}
class Category {
let name: String
let sign: [Sign]
init(name: String, sign: [Sign]) {
self.name = name
self.sign = sign
}
}
Both are used to be in TableView - Category as section title and Sign as section row. I tried to implement searchBar above tableView, but when I start type keyword I see only Category names filtered. Do you have any idea how to figure out that?
Eg.
var categories: [Category] = [
Category(name: "X", sign: [Sign(code: "X-1", name: "***"),
Category(name: "Y", sign: [Sign(code: "Y-1", name: "Yyy"),
After typing "yy" || "y" in search bar I need my tableView shows only Sign which contains "yy".
My current TableView configuration:
override func numberOfSections(in tableView: UITableView) -> Int {
return filteredCategories.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredCategories[section].sign.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
return filteredCategories[0].name
case 1:
return filteredCategories[1].name
case 2:
return filteredCategories[2].name
case 3:
return filteredCategories[3].name
default:
return "Error"
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: PropertyKeys.categorieCell, for: indexPath) as! SignTableViewCell
let categorie = filteredCategories[indexPath.section]
let sign = categorie.sign[indexPath.row]
cell.signImagemin.image = UIImage(named: sign.picture)
cell.signCodeMin.text = sign.code
cell.signDescriptionMin.text = sign.name
return cell
}
My current searchBar func:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
filteredCategories = []
let text = searchText.lowercased()
if searchText == "" {
filteredCategories = categories
} else {
for categorie in categories {
if categorie.name.lowercased().contains(searchText.lowercased()) {
let signs = categorie.sign.filter() { $0.name.contains(searchText) }
let newCat = categorie
newCat.sign = signs
filteredCategories.append(newCat)
}
}
}
self.tableView.reloadData()
}
Thank you!
Eg.: In this tableView clean
Want to see only signs which contain "A1" and Cat A above as section name
result

You just control the categorie.name contains the giving search keyword.You must add also this categorie.sign.filter({$0.name.contains(searchText)}).count != 0 to your if condition. It will be like
if categorie.sign.filter({$0.name.contains(searchText)}).count != 0{
// codes here
}
Also you declared sign in Category class with let so
let newCat = categorie
newCat.sign = signs
Above code is illegal You need to change let with var in class
Category
var sign: [Sign]

Related

Represent result of parsing JSON in tableView Swift

I start learning swift with Paul Hudson's "100 Days of Swift" and I need your advices.
I'm trying making app with country's info (capital, language, currencies etc.) and stuck with trying represent result of my JSON parsing in tableView.
This is my struct for parsing country's info from https://restcountries.com/v3.1/all
struct Country: Codable {
let name: Name
let cca2: String
let capital: [String]?
let population: Int
let currencies: [String: Currency]?
}
struct Name: Codable {
let common: String
let official: String
}
struct Currency: Codable {
let name: String?
let symbol: String?
}
I have problems with currencies. I don't understand how represent them properly in tableView. This is code of my ViewController:
import UIKit
class ViewController: UITableViewController {
var countries = [Country] ()
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "https://restcountries.com/v3.1/all"
if let url = URL(string: urlString) {
if let data = try? Data(contentsOf: url) {
parse(json: data)
return
}
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
countries.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Country", for: indexPath)
let country = countries[indexPath.row]
cell.textLabel?.text = country.name.common
cell.imageView?.image = UIImage(named: country.cca2.lowercased())
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as? DetailViewController {
vc.country = countries[indexPath.row]
present(vc, animated: true)
}
}
func parse(json: Data) {
let decoder = JSONDecoder()
do {
let jsonCountries = try decoder.decode([Country].self, from: json)
countries = jsonCountries
}
catch let error {
print(error)
}
}
}
And this is code of my DetailViewController:
import UIKit
class DetailViewController: UITableViewController {
var country: Country!
let flag = "Flag"
let general = "General"
let currency = "Currency"
var currencyName = ""
var currencySymbol = ""
lazy var sectionTitles = [flag, general, currency]
lazy var currencies = country.currencies?.values
override func viewDidLoad() {
super.viewDidLoad()
title = country.name.common
getCurrencyName()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return sectionTitles.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionTitles[section]
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch sectionTitles[section] {
case flag:
return 1
case general:
return 4
case currency:
// How make to return proper number's of rows??
return 2
default:
return 0
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch sectionTitles[indexPath.section] {
case flag:
let cell = tableView.dequeueReusableCell(withIdentifier: "Flag", for: indexPath)
if let cell = cell as? FlagCell {
cell.flagImageView.image = UIImage(named: country.cca2.lowercased())
}
return cell
case general:
let cell = tableView.dequeueReusableCell(withIdentifier: "Text", for: indexPath)
cell.textLabel?.numberOfLines = 0
switch indexPath.row {
case 0:
cell.textLabel?.text = "Common country name: \(country.name.common)"
case 1:
cell.textLabel?.text = "Official country name: \(country.name.official)"
case 2:
cell.textLabel?.text = "Capital: \(country.capital?[0] ?? "Unknown")"
case 3:
cell.textLabel?.text = "Population: \(country.population) people"
default:
return cell
}
return cell
case currency:
let cell = tableView.dequeueReusableCell(withIdentifier: "Text", for: indexPath)
cell.textLabel?.numberOfLines = 0
switch indexPath.row {
case 0:
// How to represent each currency of country?
cell.textLabel?.text = "Currency name: \(currencyName)"
case 1:
cell.textLabel?.text = "Currency symbol: \(currencySymbol)"
default:
return cell
}
return cell
default:
break
}
return UITableViewCell ()
}
func getCurrencyName () {
for currency in currencies! {
currencyName = currency.name ?? ""
currencySymbol = currency.symbol ?? ""
}
}
}
For now I understand how to represent one currency of each country, but how I can represent all currencies of each country in different rows?
Sorry for my English it's not my native language :)
I would suggest getting a sorted list of the currencies. E.g., for a given Country:
let currencies = country.currencies?.sorted { $0.0 < $1.0 }
To get the count:
let count = currencies?.count ?? 0
To get the details for a particular row, it would be:
if let (code, currency) = currencies?[indexPath.row] {
let currencyCode = code
let currencyName = currency.name
let currencySymbol = currency.symbol
}
You can access the number of currencies for each country with this, and use it in the numberOfRowsInSection method to return enough number of rows for currencies:
country.currencies.count
The rest is filling the cells in the cellForRowAt method by using the indexPath's section and row values. You should iterate over the currencies dictionary of the selected country, and display each key and value pair in the dictionary in a row.
You can do the iteration like so:
for (key, value) in dict {
// Use key and value here
}

Search name or number in `UISearchbar`

In tableViewCell I have userNameLbl with name, userClgLbl with number. I want to search and show data in tableView either name search or number search.
If user search name - based on name I can show data in tableView.
If user search number - based on number I can show data in tableView.
But how to work with both name and number for single search bar. Actually here my data is dynamic from server and number is not phone number.
UISearchBarDelegate added to my class
let searchBar = UISearchBar()
var filteredData: [Any]!
#IBOutlet weak var listTblView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// create a new cell if needed or reuse an old one
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
cell.userNameLbl.text = filteredData[indexPath.row] as? String
cell.userClgLbl.text = clg_uniq[indexPath.row] as? String
return cell
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
let strArr:[String] = clg_uniq as! [String]
filteredData = searchText.isEmpty ? clg_uniq : strArr.filter({(dataString: String) -> Bool in
// If dataItem matches the searchText, return true to include it
return dataString.range(of: searchText, options: .caseInsensitive) != nil
})
DispatchQueue.main.async {
self.listTblView.reloadData()
}
if searchText == "" {
DispatchQueue.main.async {
searchBar.resignFirstResponder()
}
}
}
//Added these lines after json parsing
self.filteredData = self.clg_uniq
self.listTblView.reloadData()
My example JSON data is
{"log" = (
{
Name = "Name1";
"clg_uniq" = 5c640e7b86e35;
},
{
Name = "Name2";
"clg_uniq" = <null>;
},
{
Name = <null>;
"clg_uniq" = 5c647af5d5c4d;
},
{
Name = "Name4";
"clg_uniq" = 5c647a0427253;
},
{
Name = <null>;
"clg_uniq" = <null>;
},
{
Name = "Name6";
"clg_uniq" = $cuniq";
},
)
}
Add following variables -
var logArray = [Dictionary<String, Any>]() // For all result
var searchedLogArray = [Dictionary<String, Any>]() // For filtered result
var searchActive = false // whenever user search anything
Replace UISearchBarDelegate -
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchActive = searchText.count > 0 ? true : false
let namePredicate = NSPredicate(format: "Name CONTAINS[c] %#", searchText)
let clgUniqPredicate = NSPredicate(format: "clg_uniq CONTAINS[c] %#", searchText)
let compoundPredicate = NSCompoundPredicate.init(orPredicateWithSubpredicates: [namePredicate, clgUniqPredicate])
searchedLogArray = logArray.filter({
return compoundPredicate.evaluate(with: $0)
})
listTblView.reloadData()
}
Replace UITableViewDataSource -
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchActive ? searchedLogArray.count : logArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// create a new cell if needed or reuse an old one
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
let logDict = searchActive ? searchedLogArray[indexPath.row] : logArray[indexPath.row]
// Name
if let name = log["Name"] as? String{
cell.userNameLbl.text = name
}else{
cell.userNameLbl.text = ""
}
// clg_uniq
if let clgUniq = log["clg_uniq"] as? String {
cell.userClgLbl.text = clgUniq
}else{
cell.userClgLbl.text = ""
}
return cell
}
I hope you are persing response as Dictionary<String, Any>
Let me know if you are still having any issue.

Show data in table view from mysql using alamofire and swiftyjson

I have a php script on my server which is just a basic sql SELECT statement which gets some data from a mysql database and it returns a number of rows.
I have used alamofire and swiftyjson to print the data out to console but I want to show it in a table view.
Due to the call not being in the same scope as the tableView code ( I think that is the reason I am getting an error which says 'Use of unresolved idenfifier')
I am not sure how to make it global but I guess I need to create a global array variable but not sure if it should just be empty?
global:
let serviceURL = "http://example.com/service.php"
I put it in a function like this:
func getUsers() {
Alamofire.request(serviceURL, method: .get).validate().responseJSON { (response) in
if response.result.isSuccess {
let userJSON : JSON = JSON(response.result.value!)
for (index,subJson):(String, JSON) in userJSON {
let firstName = subJson["first_name"].string
let lastName = subJson["last_name"].string
print(firstName)
}
} else {
print("Could not get results")
}
}
}
I need to somehow count the rows returned
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return firstName.count
}
And then actually display in the cell
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "userCell", for: indexPath)
cell.textLabel?.text = names[indexPath.row]
return cell
}
UPDATE
import UIKit
import Alamofire
import SwiftyJSON
struct User {
var firstName: String
var lastName: String
private enum CodingKeys: String, CodingKey {
case firstName = "first_name"
case lastName = "last_name"
}
}
class UserTableViewController: UITableViewController {
var users = [User]()
let serviceURL = "http://example.com/service.php"
override func viewDidLoad() {
super.viewDidLoad()
getUsers()
}
func getUsers() {
Alamofire.request(serviceURL, method: .get).validate().responseJSON { (response) in
if response.result.isSuccess {
let userJSON : JSON = JSON(response.result.value!)
for (index,subJson):(String, JSON) in userJSON {
let firstName = subJson["first_name"].string
let lastName = subJson["last_name"].string
let user = User(firstName: firstName!, lastName: lastName!)
self.users.append(user)
}
} else {
print("Could not get results")
}
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "userCell", for: indexPath)
let user = users[indexPath.row]
cell.textLabel?.text = "\(user.firstName) \(user.lastName)"
return cell
}
}
First of all you need a structure to hold your data
struct User {
var firstName: String
var lastName: String
}
Then you need an array to hold the users from the json message, declare it as an attribute in your view controller
var users = [User]()
And then make use of it in your code
func getUsers() {
Alamofire.request(serviceURL, method: .get).validate().responseJSON { (response) in
if response.result.isSuccess {
let userJSON : JSON = JSON(response.result.value!)
for (index,subJson):(String, JSON) in userJSON {
let firstName = subJson["first_name"].string
let lastName = subJson["last_name"].string
let user = User(firstName: firstName, lastName: lastName)
users.append(user)
}
} else {
print("Could not get results")
}
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "userCell", for: indexPath)
let user = users[indexPath.row]
cell.textLabel?.text = "\(user.firstName) \(user.lastName)"
return cell
}

How to Filter a search with an objects properties efficiently in swift?

Hey guys i've searched for hours and still cant find a proper way to search though my data base. I have an array of contact objects that have a username and name property and I have a "add user" view controller where the GOAL is to loop through all the users in my data base , and when searching , it widdles down the users in a UITABLEVIEW this is what I have so far.
Cliff notes of code below:
I get all my user objects from my database and store them in an array of type [contact] called "results" (custom object) then i attempt to filter the results and store those into a new array called "filteredData" Contact has type "userName" (String) which I would like to filter results by
import UIKit
import Firebase
class SearchForUsersViewController: UIViewController {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var tableView: UITableView!
var results = [Contact]()
var filteredData = [Contact]()
var isSearching = false;
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
searchBar.delegate = self;
searchBar.returnKeyType = UIReturnKeyType.done
getUserList()
}
#IBAction func dismiss(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
func getUserList(){
//populates results
staticValuesForData.instance.dataBaseUserref.observe( .value) { (snapshot) in
if let userList = snapshot.children.allObjects as? [DataSnapshot]{
for user in userList{
let name = (user.childSnapshot(forPath: staticValuesForData.instance.fName).value as! String) + " "
+ (user.childSnapshot(forPath: staticValuesForData.instance.lname).value as! String)
let contact = Contact(name: name , uid: user.key,
pic: user.childSnapshot(forPath: staticValuesForData.instance.profileUrl).value as! String,
userName: user.childSnapshot(forPath: staticValuesForData.instance.userName).value as! String )
print(contact.name)
print("user" , user)
self.results.append(contact)
}
}
}
}
}
table view extension :
extension SearchForUsersViewController : UITableViewDataSource ,
UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isSearching{
return results.count
}
return 0;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell" , for: indexPath) as! AddedMeTableViewCell;
cell.profilePicture.loadImageUsingCacheWithUrlString(urlString: filteredData[indexPath.item].picUrl)
if isSearching{
cell.userName.text = filteredData[indexPath.item].userName!
}
else
{
cell.userName.text = results[indexPath.item].userName!
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80;
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
Search extension (where the issue is )
extension SearchForUsersViewController : UISearchBarDelegate{
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text == "" || searchBar.text == nil{
view.endEditing(true)
isSearching = false;
tableView.reloadData()
}
else{
isSearching = true
ifSearchContains(word: searchBar.text!)
tableView.reloadData()
print(filteredData)
print(results)
print(searchBar.text)
}
}
func ifSearchContains(word : String)
{
for result in results{
if result.name.contains(word){
filteredData.append(result)
}else{
}
}
}
}
I have the search function above but it is not filtering , nor is the idea of it very efficient. this application is going to have thousands of users, can you please help me filter a search in an efficient way? Thank you so much
Here is the contact custom object just in case
import Foundation
class Contact : NSObject , Comparable{
let name : String!
let uid : String!
let picUrl : String!
let userName : String!
init(name : String , uid : String , pic : String , userName : String) {
self.name = name
self.uid = uid
self.picUrl = pic
self.userName = userName
}
static func ==(lhs: Contact, rhs: Contact) -> Bool {
return lhs.name == rhs.name
}
static func <(lhs: Contact, rhs: Contact) -> Bool {
return lhs.name < rhs.name
}
}

Table view from array index out of range

I'm using an array to read data from a database, Currently I have 8 items in the array. I am trying to make a table where I have a section header. Currently I have 4 sections and I have set that properly and it works. It also works running the first time but when I try to scroll back I get an index out of range. I am using myarray[myindex] to set the cell data for each item and that is not working.
It seems that I need to break up my data into 4 sections that contains only the data for each section to let the table view control it properly. The data can contain any number of sections.
Is there a better way to do this?
I have attached a pic to describe the problem.
Thanks
Adding code on request.
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
print("Returning Sections - > \(sections)")
return sections //seems to work
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
print("Return number of rows in section -> \(noRowsInSection[section])")
return noRowsInSection[section] // seems to work
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionHeader[section] // seems to work
}
override func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
// Format for section Headers
let header:UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
header.textLabel!.textColor = UIColor.blueColor()
UIColor.blueColor()
header.textLabel!.font = UIFont.boldSystemFontOfSize(12)
header.textLabel!.frame = header.frame
header.textLabel!.textAlignment = NSTextAlignment.Right
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("OurCell", forIndexPath: indexPath) as! OurTableViewCell
print("myindex - > \(myindex) row -> \(indexPath.row)")
cell.OurCellLabel.text = MyHouses[myindex].getAddressDetails() // End configure houses.cell
//cell.OurCellLabel.text = MyHouses[indexPath.row].getAddressDetails() // End configure houses.cell
myindex++ // PROBLEM HERE - GOES OUT OF RANGE
return cell
}
Here I am getting data from the sqlite DB
func GetListOfHousesFromDB() {
let docsDir = dirPaths[0]
let databasePath = docsDir.stringByAppendingString("/newdb.db")
if fileMgr.fileExistsAtPath(databasePath as String) {
let houseDB = FMDatabase(path: databasePath as String)
if houseDB.open() {
var noRows: Int = 0
var sql = "select count(Address) as cnt from Houses" // Define Query
houseDB.executeStatements(sql) // Execute Query
let results:FMResultSet? = houseDB.executeQuery(sql,withArgumentsInArray: nil) //Get results from Query
if results?.next() == true {
let cnt = (results?.stringForColumn("cnt"))! // Retrieve number of rows from DB
noRows = Int(cnt)!
}
var i = 0
sql = "SELECT Address, Street, City, State, Zip from Houses ORDER BY State, City, Street, Address" // Define Query
houseDB.executeStatements(sql) // Execute Query
let results2:FMResultSet? = houseDB.executeQuery(sql,withArgumentsInArray: nil) // Get results from Query
while results2?.next() == true {
MyHouses.append(newhouse())
MyHouses[i].address = (results2?.stringForColumn("Address"))!
MyHouses[i].street = (results2?.stringForColumn("Street"))!
MyHouses[i].city = (results2?.stringForColumn("City"))!
MyHouses[i].state = (results2?.stringForColumn("State"))!
MyHouses[i].zip = (results2?.stringForColumn("Zip"))!
print("Address -> \(i) \(MyHouses[i].getAddressDetails())")
i++
}
}
houseDB.close()
}
}
Based on your other post, what you need is an updated House model and updated data structure for handling data for your table view.
House - Model class
struct House {
var address: String
var street: String
var city: String
var state: String
var zip: String
func getAddressDetails() -> String {
return "\(address) \(street) \(city) \(state) \(zip)"
}
func getCityState() -> String {
return "\(city) - \(state)"
}
}
Helper Class for loading data
class HouseDataHelper {
private static let _sharedInstance = HouseDataHelper()
var myHouses: Dictionary<String, [House]> = [:]
private init() {
loadHouseData()
}
static func sharedInstance() -> HouseDataHelper {
return _sharedInstance
}
private func loadHouseData() {
var houses = [House]()
//Populating your actual values here. GetListOfHousesFromDB()
//Loading dummy data for testing
var sectionHeader = ""
for i in 0...4 {
sectionHeader = "Header \(i)"
houses += [House(address: "Address1", street: "Street1", city: "City1", state: "State1", zip: "Zip1")]
houses += [House(address: "Address2", street: "Street2", city: "City2", state: "State2", zip: "Zip2")]
houses += [House(address: "Address3", street: "Street3", city: "City3", state: "State3", zip: "Zip3")]
houses += [House(address: "Address4", street: "Street4", city: "City4", state: "State4", zip: "Zip4")]
houses += [House(address: "Address5", street: "Street5", city: "City5", state: "State5", zip: "Zip5")]
myHouses.updateValue(houses, forKey: sectionHeader)
houses = []
}
}
}
Table View Controller
class TableViewController: UITableViewController {
var houses = HouseDataHelper.sharedInstance().myHouses
var sectionHeaders: [String] = []
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
sectionHeaders = Array(houses.keys.sort())
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return houses.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let rows = houses[sectionHeaders[section]] {
return rows.count
}
return 0
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionHeaders[section]
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//Populate cells based on "houses"
}
}

Resources