How to add alphabetic sections in TableView from database using swift 3 - ios

I'v created a TableView that shows data from my database, now I want to add alphabetic sections into my table my database already sorted alphabetically.
My problems:
1 - I can't make the Dictionary to accesses only the first column of the database (the name column).
2 - I don't know how to get the first letter of the names and store every item in the letter the name start with.
If you know a better way than using a Dictionary I'm open to any suggestions.
My code:
class crimesTableViewController: UITableViewController {
var marrCrimesData : NSMutableArray!
#IBOutlet weak var crimesTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
self.getCrimesData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func getCrimesData()
{
marrCrimesData = NSMutableArray()
marrCrimesData = ModelManager.getInstance().getAllCrimesData()
crimesTableView.reloadData()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return marrCrimesData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: crimesTableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! crimesTableViewCell
let crime: CrimesInfo = marrCrimesData.object(at: indexPath.row) as! CrimesInfo
cell.nameLabel.text = crime.Name
cell.detailLabel.text = crime.Detail
cell.timeLabel.text = crime.Time
return cell
}

Related

TableView return repeated items every time app runs

So, I am using Realm database and my TableView returns new set of data every time. So, for the first time, I got 3 items. The second time it's 6 items and etc.
import UIKit
import RealmSwift
class TableViewController: UITableViewController {
var ModelName = [String]()
var Power = [String]()
func addPanel () {
let realm = try! Realm()
let allPanels = realm.objects(Panel)
try! realm.write {
realm.add(Panel(model: "Hyundai", power: 260))
realm.add(Panel(model: "Honda", power: 420))
realm.add(Panel(model: "Siemens", power: 280))
}
tableView.reloadData()
for i in allPanels {
ModelName.append(i.model)
Power.append("\(i.power)")
}
}
override func viewDidLoad() {
super.viewDidLoad()
addPanel()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return ModelName.count //changed from 3
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:TableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
//connect NameLabel cell to the name of Model and PowerLabel cell to the power
cell.NameLabel.text = ModelName[indexPath.row]
cell.PowerLabel.text = Power [indexPath.row]
return cell
}
If I limit my the number of rows to 3, the app works.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return ModelName.count //changed from 3
}
I will appreciate any help. Thank you
I believe it's because every time this controller is loaded, you add three objects to Realm. Since by default, update is false, you will be adding three new objects to Realm every time. If you change update to true, then it should use the primary key of the object and "update" these objects every view controller load.
public func add(_ object: Object, update: Bool = false)

Retrieving firebase children and populating them in a UITableView

Trying to query firebase children and retrieve a snapshot array of their data into a tableview. Not sure if I am implementing this correctly, but I am not the getting a runtime error. However, my tableview is just white with no objects displaying. Some feedback would be helpful. Thanks.
Here is my FB JSON tree structure
Here is my User class (var userList = User)
class CDetailTableViewController: UITableViewController {
static var imageCache = NSCache<AnyObject, UIImage>()
var userList = [User]()
var ref = FIREBASE.FBDataReference().ref
var refHandle: UInt!
override func viewDidLoad() {
super.viewDidLoad()
ref = FIREBASE.FBLink().FBref
configureCell()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return userList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! CDetailTableViewCell
cell.priceLabel?.text = userList[indexPath.row].priceLabel
cell.titleLabel?.text = userList[indexPath.row].titleLabel
cell.itemPhoto?.image = userList[indexPath.row].objectImage
return cell
}
func configureCell(){
let ref = FIRDatabase.database().reference()
let userID = FIRAuth.auth()?.currentUser?.uid
refHandle = ref.child("Enterpriser Listings").child("Sell Old Stuff - Listings").child(userID!).observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String : AnyObject] {
print("get dictionary")
print(dictionary)
let user = User()
user.setValuesForKeys(dictionary)
self.userList.append(user)
// Get user value
DispatchQueue.main.async {
print("reloaded")
self.tableView.reloadData()
}
}
})
}
/*
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
*/
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
May be the problem is with your Firebase reference, try like this way.
ref.child("Enterpriser Listings").child("Sell Old Stuff - Listings").observe(.value, with: { (snapshot:FIRDataSnapshot) in
var users = [User]()
for child in snapshot.children {
print("\((sweet as! FIRDataSnapshot).value)")
if let dictionary = child.value as? [String : AnyObject] {
let user = User()
user.setValuesForKeys(dictionary)
users.append(user)
}
}
self.userList = users
self.tableView.reloadData()
})
Simple question. Have you delegated your tableview?
class YourController: < other >, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() { //for example this function
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
}

Swift - table is empty after moving between controllers

I'm updating existing Objective-C app.
There is a structure:
AppDelegate
- creates mainBackgroundView and adding subview with UITabBarController
I have in one "Tab" HistoryViewController:
#objc class HistoryViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let historyTableViewController = HistoryTableViewController()
self.view.addSubview(historyTableViewController.view)
}
}
And HistoryTableViewController:
import UIKit
#objc class HistoryTableViewController: UITableViewController {
// Mark: properties
var historyCalls = [HistoryItem]()
// Mark: private methods
private func loadSimpleHistory() {
let hist1 = HistoryItem(personName: "Test", bottomLine: "text", date: "10:47")
let hist2 = HistoryItem(personName: "Test 2", bottomLine: "text", date: "10:47")
let hist3 = HistoryItem(personName: "Test 3", bottomLine: "text", date: "10:47")
historyCalls += [hist1, hist2, hist3]
}
override func viewDidLoad() {
super.viewDidLoad()
self.loadSimpleHistory()
self.tableView.register(UINib(nibName: "HistoryCallTableViewCell", bundle: nil), forCellReuseIdentifier: "HistoryCallTableViewCell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return historyCalls.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "HistoryCallTableViewCell", for: indexPath) as? HistoryCallTableViewCell else {
fatalError("Coulnd't parse table cell!")
}
let historyItem = historyCalls[indexPath.row]
cell.personName.text = historyItem.personName
cell.bottomLine.text = historyItem.bottomLine
cell.date.text = historyItem.date
return cell
}
}
When I open the navigation tab with HistoryViewController for the first time, table appers with data. When I click into the table or switch navTab and then go back, table is not there anymore.
When I switch to another app and then go back, table is there again.
How to fix this?
Thank you
Call data method in viewwillappear and reload the table..
override func viewWillAppear() {
super.viewWillAppear()
self.loadSimpleHistory()
self.tableview.reloadData()
}

Reload UITableview after back

I have simple table on my View. Another view have array with some values. When I back, I want to reload table with new values, but dont work.
My class:
let textCellIdentifier = "cell"
var menu:[[String]] = [[]]
var buscaEmp:BuscadorEmpresa = BuscadorEmpresa()
#IBOutlet weak var tablaVista: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
recuperaEmpresas()
tablaVista.delegate = self
tablaVista.dataSource = self
}
func recuperaEmpresas(){
menu = buscaEmp.getEmpresas()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menu.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as! CustomTableViewCell
let row = indexPath.row
cell.nombreEmp.text = menu[row][0]
return cell
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
recuperaEmpresas()
tablaVista.reloadData()
}
I use viewWillAppear to reload table before reopen the view.
in viewWillAppear, you have to call recuperaEmpresas() and after it, call tableView.reloadData().
With this, it will refill the menu datasource with fresh data from recuperaEmpresas() and reload the table view with the new datasource values.
Edit :
And be sure that recuperaEmpresas() refresh data with new data, if it's always the same, you won't see any changes...

PFQuery first returning 6 items then 3 in a UITableViewController

He everyone,
Im pulling my hears out for a whole day for the following issue. My back-end is in Parse and i am doing a query on my table "events" in a UITableViewController. The problem is that the query returns the complete data in the ViewDidLoad but not in my tableView method. In my tableView im only getting 3 items returned. Im aware of that parse query doing a Asynchronously call but why its returning 3 items?
I would be gratefull if somebody can help me out here.
Here is my code:
class EventOverViewController: UITableViewController {
var events:Array = [AnyObject]();
var imageContainer : UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None;
self.retrieveInfoFromParse();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return self.events.count
}
func queryForTable() -> PFQuery {
let getEvents = PFQuery(className:"Event");
return getEvents;
}
func retrieveInfoFromParse(){
self.queryForTable().findObjectsInBackgroundWithBlock { (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
for object in objects! {
self.events.append(object);
}
//RETURNING 6 ITEMS
print(self.events);
self.tableView.reloadData();
}
}
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 230;
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("EventCell", forIndexPath:indexPath) as! EventTableViewCell
let eventData = self.events[indexPath.row];
//ONLY returning 3 ITEMS, WHY?
print(eventData);
return cell
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow!
let destinationVC = segue.destinationViewController as! RootMainViewController
var secondEventData : Event!
secondEventData = self.events[indexPath.row] as! Event;
destinationVC.title = secondEventData.eventName;
destinationVC.event = secondEventData;
}
}

Resources