empty tableview cell for at index path row is not called - ios

All the tableview functions are working except cell for row index path .
The problem maybe that foods array is empty so the number for rows is 0 so the cell for row at index path is not called
#IBOutlet weak var foooods: UITableView!
var databaseref = Database.database().reference()
var img : AnyObject?
var foods = [String?]()
override func viewDidLoad() {
super.viewDidLoad()
self.databaseref.child("basic food").observe(.childAdded, with: {( snap: DataSnapshot) in
let snapp = snap.value as! [String:AnyObject]
if let x = snapp["name"] as! String? {
self.foods.insert(x, at: 0)
//self.foods.append(x)
}
})
self.foooods.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.foods.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("difufuehf")
let cell : foodsTableViewCell = tableView.dequeueReusableCell(withIdentifier: "aupa", for:indexPath) as! foodsTableViewCell
print("fufvksdfvysdgfvjdsgfdsygfvds,jhvjsdvsdjvguydsfgdsylfgdsyfgsdlygfsiygf")
if let foo = foods[indexPath.row] {
print(foo)
cell.food.text = foo
}
return cell
}

This must be a duplicate but I can't find one.
Your issue is that you call reloadData in the wrong place which results in it being called far too soon. You need to call it inside the completion block, after you update your data model.
And you need to make sure it gets called on the main queue.
override func viewDidLoad() {
super.viewDidLoad()
self.databaseref.child("basic food").observe(.childAdded, with: {( snap: DataSnapshot) in
if let snapp = snap.value as? [String:Any], let x = snapp["name"] as? String {
self.foods.insert(x, at: 0)
//self.foods.append(x)
DispatchQueue.main.async {
self.foooods.reloadData()
}
}
})
}
Note that I also fixed the way the value is obtained. You really need to avoid force unwrapping and force casting.

Related

Swift Table View Cell Changing Data

I have table view controller. My problem; The cell in my table view changes every time I enter the view controller. For example; There are 2 data (address-1 and address-2). The first row is address-1, the second row is address-2, when I re-enter the page, the cells change. How can I fix this problem. Thanks
import UIKit
import Firebase
import MapKit
class DenemeTableViewController: UITableViewController {
var ref: DatabaseReference!
let user: User = Auth.auth().currentUser!
var adresListesi = [Adresler]()
var adres: Adresler!
#IBOutlet var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.table.delegate = self
self.table.dataSource = self
Adresdefteri()
}
override func viewWillAppear(_ animated: Bool) {
Adresdefteri()
table.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return adresListesi.count
}
//prob.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! DenemeTableViewCell
let adresList = self.adresListesi[indexPath.row]
cell.textLabel?.text = adresList.adresname
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath:IndexPath) {
self.performSegue(withIdentifier: "DENEMEHARİTAGO", sender: indexPath.row)
}
func Adresdefteri() {
ref = Database.database().reference()
let adreslerim = ref
adreslerim?.child("locations").child(user.emailWithoutSpecialCharacters).child("Adresler").observe( .value) { [self] (snapshot) in
if let gelenVeributunu = snapshot.value as? [String:AnyObject]{
self.adresListesi.removeAll()
for gelenSatirVerisi in gelenVeributunu {
if let sozluk = gelenSatirVerisi.value as? NSDictionary {
let key = gelenSatirVerisi.key
let adresname = sozluk["adresname"] as? String ?? ""
let latitude = sozluk["latitude"] as? Double ?? 0.0
let longitude = sozluk["longitude"] as? Double ?? 0.0
let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let adres = Adresler(adresname: adresname, latitude: latitude, longitude: longitude, adresid: key)
self.adresListesi.append(adres)
}
}
DispatchQueue.main.async {
self.table.reloadData()
}
}
}
tableview
Sort the data source array after creating it and reloading the table view, that way it stays consistent. Cheers!
self.arrayName = arrayName.sorted(by: { $0.valueToSortByInArray > $1.valueToSortByInArray })
You just have to sort the adresListesti to make sure the order is consistent.
An example would be:
adresListesi.sort { $0.adresname < $02.adresname }
Put that right before DispatchQueue.main.async and it should work.

How to Sort TableViewCells by date string

As shown below I want to sort my TableViewCells by the date. For this I have the time which is also called timestampName.
Right before I reload the data, I tried to sort it, but somehow this has no effect. It also throws me a warning, that I dont use the result of the sorted by. I understand this, but I dont know how to fix that.
import UIKit
import Firebase
class popularViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet var table: UITableView!
// var models = [PhotoPost]()
var texttt = [TextPost]()
override func viewDidLoad() {
super.viewDidLoad()
gettingPosts()
table.register(popularTableViewCell.nib(), forCellReuseIdentifier: popularTableViewCell.identifier)
table.register(featuredTableViewCell.nib(), forCellReuseIdentifier: featuredTableViewCell.identifier)
table.register(textTableViewCell.nib(), forCellReuseIdentifier: textTableViewCell.identifier)
table.delegate = self
table.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return texttt.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: textTableViewCell.identifier, for: indexPath) as! textTableViewCell
cell.configure(with: self.texttt[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 300
}
func gettingPosts(){
let db = Firestore.firestore()
let postsRef = db.collection("posts")
postsRef.addSnapshotListener { (querySnapshot, error) in
guard let snapshot = querySnapshot else {
print("Error fetching snapshots: \(error!)")
return
}
snapshot.documentChanges.forEach { diff in
if (diff.type == .added){
let data = diff.document.data()
let Name = data["username"] as! String
let text = data["description"] as! String
let likes = data["likes"] as! Int
let typ = data["postType"] as! Int
let pfp = data["profileImage"] as! String
let uid = data["uid"] as! String
let pic = data["picture"]
let time = data["time"] as! String
if typ == 0{ // Text post
let dasDing = TextPost(numberOfComments: 0, username: Name, timestampName: time, userImageName: pfp, textName: text)
self.texttt.append(dasDing)
self.texttt.sorted(by: { $0.timestampName < $1.timestampName }) //WARNING: Result of call to 'sorted(by:)' is unused
self.table.reloadData()
}
struct TextPost {
let numberOfComments: Int
let username: String
let timestampName: String
let userImageName: String
let textName: String
}
Use sort instead of sorted. The sorted method returns a new sorted array, on the other hand, the sort method sorts the array on which it was called.
self.texttt.sort(by: { $0.timestampName < $1.timestampName })
This should also work, using sorted:
self.texttt = self.texttt.sorted(by: { $0.timestampName < $1.timestampName })

The snapshot is not represented correctly

This is the code responsible for uploading text of a post for a blogging app the text of the post is retrieved correctly and saved in snapshot
struct postt {
let username : String!
let textofpost : String!
}
class TableViewController: UITableViewController {
var databaseref = FIRDatabase.database().reference()
var loggedinuser : AnyObject?
var posts = [postt]()
override func viewDidLoad() {
super.viewDidLoad()
self.loggedinuser = FIRAuth.auth()?.currentUser
self.databaseref.child("users").child(self.loggedinuser!.uid).observeSingle
Event(of: .value) {(snapshot:FIRDataSnapshot) in
let snapshot = snapshot.value as! [String:AnyObject]
let username = snapshot["name"] as? String
self.databaseref.child("posts").queryOrderedByKey().observe(.childAdded, with: {( snapshot: FIRDataSnapshot) in
let snapshot = snapshot.value as? NSDictionary
The next variable textofpost doesn't contain anything and i don't know what is the problem so when i represent the cell only the label appears which has a snapshot from the path name in the node users
let textofpost = snapshot?["text"] as? String
self.posts.insert(postt(username : username, textofpost : textofpost), at: 0)
// self.feeds.reloadData()
self.tableView.reloadData()
}
)}
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.posts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let label = cell.viewWithTag(1) as! UILabel
label.text = posts[indexPath.row].username
let textview = cell.viewWithTag(2) as! UITextView
textview.text = posts[indexPath.row].textofpost
return cell
}
}

Can't present data in table view cell

I am trying to retrive each row from database and keep value in dictionary. After that I have created a array of dictionary. But when i am trying to show each value of dictionary in table cell, i can't . Here is my code
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
var borrowerInformation:NSMutableDictionary? = NSMutableDictionary();
var borrowerName:String = ""
var givenDate:String = ""
var borrower:NSMutableArray = []
override func viewDidLoad() {
super.viewDidLoad()
dataQuery()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return self.borrower.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! BorrowerLanderTableViewCell
cell.borrowerName.text = self.borrower[indexPath.row] as? String
return cell
}
func dataQuery(){
let queryBorrower = PFQuery(className:"BorrowerLander")
queryBorrower.whereKey("borrowerLander", equalTo: 0)
queryBorrower.whereKey("userId", equalTo: (PFUser.currentUser()?.objectId)!)
queryBorrower.findObjectsInBackgroundWithBlock {
(objects: [PFObject]?, error: NSError?) -> Void in
self.borrower = NSMutableArray()
if error == nil {
if let borrowerData = objects {
for object in borrowerData {
self.borrowerName = object["name"] as! String
self.givenDate = object["givenDate"] as! String
self.borrowerInformation = [ "borrowerName": self.borrowerName,"givenDate":"self.givenDate"]
self.borrower.addObject(self.borrowerInformation!)
}
}
}
self.tableview.reloadData()
}
}
}
Here, i have just added main part of the code. Please tell me how can i show value of array of the dictionary in table view cell?
I don't know how you did the setup but an issue could be that you have not set your tableviews delegate and datasource to the controller you are working with.
self.tableView.dataSource = self
self.tableView.delegate = self
I'm also wondering if you did implement the numberOfRows and numberOfSections delegate methods.
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return borrower.count
}
and
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
Also when setting the text you need to actually use the name string you added to the dictionary
let borrower = self.borrower[indexPath.row]
if let name = borrower["borrowerName"] as? String{
cell.borrowerName.text = name
} esle {
cell.borrowerName.text = "error"
}
Also declare your data array as
var borrower:[[String: AnyObject]] = []
Extra edit:
I do want to say that I really think you should use a custom object here instead of an dictionary
class Borrower {
var name: String
var givenDate: String
//etc.
init(name: String, givenDate: String) {
self.name = name
self.givenDate = givenDate
}
}
enabling the following
var borrower:[Borrower] = []
and in the query:
for object in borrowerData {
if let name = object["name"] as? String, givenDate = object["givenDate"] as? String {
self.borrower.append(Borrower(name: name, givenDate: giverDate))
}
}
First, make sure you've set the dataSource and delegate for your table view to your view controller. Then, the function tableView:cellForRowAtIndexPath: will never get called unless you implement tableView:numberOfRowsInSection. The default implementation of that function returns 0. Try implementing this:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return borrower.count
}
Also, if the code inside of queryBorrower.findObjectsInBackgroundWithBlock { is actually in the background, you need to dispatch your table view reload to the main thread. Like this:
dispatch_async(dispatch_get_main_queue(), { [weak self] () -> Void in
self?.tableView.reloadData()
})
You need to implement numberOf... dataSource delegate first:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int

Populating user image and text posts, compiles and runs but cells are empty. Parse Swift

I am trying to populate my feed of images and text users post. The code compiles and runs but I get empty cells.
var titles = [String]()
var locations = [String]()
var dates = [String]()
var imageFiles = [PFFile]()
override func viewDidLoad() {
super.viewDidLoad()
var privacySettingQuery = PFQuery(className: "Posts")
privacySettingQuery.whereKey("privacy", equalTo: true)
privacySettingQuery.findObjectsInBackgroundWithBlock { (objects, error) -> Void in
if let objects = objects {
for object in objects {
self.titles.append(object["name"] as! String)
self.dates.append(object["dateTime"] as! String)
self.locations.append(object["location"] as! String)
self.imageFiles.append(object["imageFile"] as! PFFile)
}
}
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return titles.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell {
let postsCell = tableView.dequeueReusableCellWithIdentifier("PostsCell", forIndexPath: indexPath) as! PostsCell
postsCell.postImage.image = UIImage(named: "Post-Image- Placeholder-1.png")
postsCell.postTitle.text = titles[indexPath.row]
postsCell.postLocation.text = locations[indexPath.row]
postsCell.postDate.text = dates[indexPath.row]
return postsCell
}
Any help would be appreciated. Also is there a better way to do this other than using arrays?
To solve the empty issue.You need call tableView.reloadData() after you got the objects.
Model class like
class Post: NSObject {
var title: String
var location: String
var date: NSDate
var imageFile: PFFile
}
And in viewController use
var posts: [Post]?
instead of the 4 arrays
When this code is being called
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return titles.count
}
The value for titles.count is still 0. After you finish fetching the info from parse and you have values for the arrays you must reload the UITableView. To do this make an outlet for the UITableView and call it tableView. Then call this code tableView.reloadData()
Hope this helps!!

Resources