Array with key in swift - uitableview

i am using this code to get text from array with key
This code in view did load
if let rs = db.executeQuery("select * from myTable", withArgumentsInArray: nil) {
while rs.next() {
let id = rs.stringForColumn("id")
let text1 = rs.stringForColumn("text")
dataArray.addObjectsFromArray(NSArray(objects:NSDictionary(object:NSArray(objects: id, text1), forKey:NSArray(objects: "id", "texti"))))
}
} else {
println("executeQuery failed: \(db.lastErrorMessage())")
}
...
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = dataArray[indexPath.row].objectForKey("texti") as? String
return cell
}
The cell label text is null, why?
println("dataArray: \(dataArray)")
dataArray: (
{
(
id,
texti
) = (
1,
John
);
},
{
(
id,
texti
) = (
2,
Mark
);
},
{
(
id,
texti
) = (
3,
Marry
);
}
)
Is there a problem in this?
I am using same code in objective-c and its working probably

Call self.tableView.reloadData() after you retrieve the dataArray. Change the dataArray.addObjects line to
dataArray.addObject(["id":id,"texti" : text1])
if let rs = db.executeQuery("select * from myTable", withArgumentsInArray: nil) {
while rs.next() {
let id = rs.stringForColumn("id")
let text1 = rs.stringForColumn("text")
dataArray.addObject(["id":id,"texti" : text1]) // Added Line
}
self.tableview.reloadData() //Added Line
} else {
println("executeQuery failed: \(db.lastErrorMessage())")
}
Inside cellForRowAtIndexPath
if let txt = dataArray[indexPath.row].objectForKey("texti") as? String
{
cell.textLabel?.text = txt
}

Related

Hide imageView and Label by setting some kind of flag

Can you guys give me some help to hide the image and name if the message it's from the same user... I want only to show it for the first message...and if that user send more not to show anymore until another Id appear... like whatsapp does it..
currently I m having like this to show u an example
[![enter image description here][1]][1]
var isTheSameUser = false
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let selectedChat = chat[indexPath.row]
let myId = String(describing:UserDefaults.standard.value(forKey: "user_id")!)
let messageUserId = String(describing:selectedChat.owner_id)
if messageUserId == myId {
return myMessageCell(indexPath: indexPath)
}else {
return userMessageCell(indexPath: indexPath)
}
}
func myMessageCell(indexPath :IndexPath) -> UITableViewCell {
let cell = self.mainTableView.dequeueReusableCell(withIdentifier: "MyMessageTableViewCell", for: indexPath) as! MyMessageTableViewCell
let selectedChat = self.chat[indexPath.row]
let myId = String(describing:UserDefaults.standard.value(forKey: "user_id")!)
// Show only for the first message
// photo image
if !isTheSameUser {
cell.profileImageView.isHidden = false
cell.profileNameLabel.isHidden = false
} else {
cell.profileImageView.isHidden = true
cell.profileNameLabel.isHidden = true
}
if let userInfo = getUserMemberOf(userId: messageUserId) {
cell.profileImageView.imageFromURL(urlString: userInfo["photo"] as! String)
} else {
cell.profileImageView.image = #imageLiteral(resourceName: "accountIcon")
}
cell.profileNameLabel.text = "\(String(describing: cell.userProfileInfo!["name"]!))"
return cell
You need check the previous chat messsage id like for every message
if indexPath.row != 0 {
let prevItem = chat[indexPath.row - 1]
let currentItem = chat[indexPath.row]
if prevItem.owner_id! == currentItem.owner_id! {
// hide label and image
}else {
// show them
}
}
else {
// show them
}

Screen Hangs and terminated

Screen gets hanged and terminated. I have trace down that because of my while loop ,screens hanged and app terminated.
While loop runs only of 10 times. when I reopen my application my Data is got saved.
How to null or deallocate the UITableViewcell
let itemcell:TableViewCell = self.tableView.cellForRow(at: item) as! TableViewCell
Since self.tableView.dequeueReusableCell(withIdentifier: "listdetails", for: item) returning empty value .I have to use cellforRow.
Please provide input on this.
#IBAction func saveButton(_ sender: UIBarButtonItem) {
let ndx = IndexPath(row:0, section: 0)
var counter:Int = 0
let cell = self.tableView.cellForRow(at: ndx) as! TableViewCell
let locationNameCell = self.tableView.cellForRow(at: IndexPath(row:1, section: 0)) as! TableViewCell
let shoppingDetails = ShoppingDetails(context:managedContext)
let storeName = cell.storeName.text!
let storeFlag = validateShoppingList(storeName: storeName)
if storeFlag == true {
let shoppingDetails = ShoppingDetails(context:managedContext)
var listDetails :ListDetails!
while counter < sectionRowCount {
let item = IndexPath(row:counter, section: 1)
var itemcell = self.tableView.cellForRow(at: item) as! TableViewCell
let list = shoppingDetails.shoppingToList?.mutableCopy() as! NSMutableSet
listDetails = ListDetails(context:managedContext)
let listItem = itemcell.listItem.text!.trimmingCharacters(in: .whitespaces)
listDetails.listItem = listItem
var qty = itemcell.qtytextfield.text!
if qty.isEmpty {
qty = "0"
}
var units = itemcell.unitstextfield.text!
if units.isEmpty {
units = ""
}
listDetails.qty = Int64(qty)!
listDetails.units = itemcell.unitstextfield.text!
listDetails.isChecked = false
list.add(listDetails)
shoppingDetails.addToShoppingToList(list)
counter = counter + 1
list.removeAllObjects()
}
shoppingDetails.storeName = storeName
if locationNameCell.locationName.text != nil {
shoppingDetails.location = locationNameCell.locationName.text!
}
shoppingDetails.initialLetter = (cell.storeName.text!).first?.description
let seqNo:Int = ShoppingDetails.getSeqNo(managedObjectContext: managedContext) + 1
shoppingDetails.seqNo = Int32(seqNo)
coreData.saveContext()
let vc = storyboard!.instantiateViewController(withIdentifier: "StoreDisplayController") as! StoreDisplayController
vc.managedContext = managedContext
vc.coreData = coreData
vc.storeName = cell.storeName.text!
// managedContext.delete(shoppingDetails)
// managedContext.delete(listDetails)
// self.present(vc, animated:true, completion:nil)
// self.navigationController?.popToViewController(vc, animated: true)
self.navigationController?.pushViewController(vc, animated: true)
}
enter image description here
Save your data in this method as the user will scroll to fill all content
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// ...
//fill model array parameters from cell properties before data lost
var itemcell = self.tableView.cellForRow(at: indexPath) as! TableViewCell
let list = shoppingDetails.shoppingToList?.mutableCopy() as! NSMutableSet
listDetails = ListDetails(context:managedContext)
let listItem = itemcell.listItem.text!.trimmingCharacters(in: .whitespaces)
listDetails.listItem = listItem
var qty = itemcell.qtytextfield.text!
if qty.isEmpty {
qty = "0"
}
var units = itemcell.unitstextfield.text!
if units.isEmpty {
units = ""
}
listDetails.qty = Int64(qty)!
listDetails.units = itemcell.unitstextfield.text!
listDetails.isChecked = false
list.add(listDetails)
shoppingDetails.addToShoppingToList(list)
}
then when save button is clicked check that model array for empty item and scroll to that indexpath to fill

uitableview cell cellForRowAtindexPath fetch first letter pick from name in swift3

I have a custom cell for my UITableView, I will show first characters of the item name like this"below image"
so my question is how to create it how to fetch first letter pick from name data fetch via json.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ProjectTabTableViewCell
cell.colorViewOutlet.layer.cornerRadius = 25.0
let projectLst = projectList[indexPath.row]
let str = projectLst.NameEN
print(str?.characters.first?.description ?? "");
projectNameFirst = [str?.characters.first?.description ?? ""]
print(projectNameFirst)
cell.wordsLabel?.text = projectNameFirst[indexPath.row]
cell.nameLabel?.text = projectLst.NameEN
cell.colorViewOutlet.backgroundColor = .random
return cell
}
let stringInput = "Ramu"
let stringInputArr = stringInput.components(separatedBy: " ")
var stringNeed = ""
for string in stringInputArr {
stringNeed = stringNeed + String(string.characters.first!)
}
print(stringNeed)
To get first character from string use below code
let str = "\(projectLst.NameEN)"
var result = ""
if str.characters.count > 0{
result = String(str.characters.prefix(1)) // which will return your first charcter
} else {
result = "" // result will be empty if string is empty
}
cell.wordsLabel?.text = result
Hope this will help you

Swift: Table View is only returning one cell

I'm attempting to load a table view with two different prototype cells. profileCell should only load once and at the top of the table view. dogCell should count an array of dog objects named dogs downloaded from firebase. Currently, only the first cell is displaying correctly.
I think the numberOfRowsInSection method isn't accurately counting the dog objects in the dogs array. When I put a breakpoint on return dogs.count + 1 and po dogs.count the debugger keeps outputting 0.
When I use return dogs.count the table view loads but with only the profile cell. If I use return dogs.count + 1(to account for the profile cell at the top) an exception is thrown when constructing dogCell: "fatal error: Index out of range"
Perhaps I need to change the way my tableview is reloading data?
Here's my code:
class DogTableViewController: UITableViewController {
var user = User()
let profileCell = ProfileTableViewCell()
var dogs = [Dog]()
override func viewDidLoad() {
super.viewDidLoad()
let userDogRef = Database.database().reference().child("users").child(user.uid!).child("dogs")
let userProfileImageView = UIImageView()
userProfileImageView.translatesAutoresizingMaskIntoConstraints = false
userProfileImageView.widthAnchor.constraint(equalToConstant: 40).isActive = true
userProfileImageView.heightAnchor.constraint(equalToConstant: 40).isActive = true
userProfileImageView.layer.cornerRadius = 20
userProfileImageView.clipsToBounds = true
userProfileImageView.contentMode = .scaleAspectFill
userProfileImageView.image = UIImage(named: "AppIcon")
navigationItem.titleView = userProfileImageView
//MARK: Download dogs from firebase
userDogRef.observe(.childAdded, with: { (snapshot) in
if snapshot.value == nil {
print("no new dog found")
} else {
print("new dog found")
let snapshotValue = snapshot.value as! Dictionary<String, String>
let dogID = snapshotValue["dogID"]!
let dogRef = Database.database().reference().child("dogs").child(dogID)
dogRef.observeSingleEvent(of: .value, with: { (snap) in
print("Found dog data!")
let value = snap.value as? NSDictionary
let newDog = Dog()
newDog.name = value?["name"] as? String ?? ""
newDog.breed = value?["breed"] as? String ?? ""
newDog.creator = value?["creator"] as? String ?? ""
newDog.score = Int(value?["score"] as? String ?? "")
newDog.imageURL = value?["imageURL"] as? String ?? ""
newDog.dogID = snapshot.key
URLSession.shared.dataTask(with: URL(string: newDog.imageURL!)!, completionHandler: { (data, response, error) in
if error != nil {
print(error!)
return
}
newDog.picture = UIImage(data: data!)!
self.dogs.append(newDog)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}).resume()
})
}
})
tableView.estimatedRowHeight = 454
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dogs.count + 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let profileCell = tableView.dequeueReusableCell(withIdentifier: "profileCell", for: indexPath) as! ProfileTableViewCell
profileCell.nameLabel.text = user.name
profileCell.totalReputationLabel.text = String(describing: user.reputation!)
profileCell.usernameLabel.text = user.username
return profileCell
} else {
let dogCell = tableView.dequeueReusableCell(withIdentifier: "dogCell", for: indexPath) as! DogTableViewCell
dogCell.dogBreedLabel.text = dogs[indexPath.row].breed
dogCell.dogNameLabel.text = dogs[indexPath.row].name
dogCell.dogScoreLabel.text = String(describing: dogs[indexPath.row].score)
dogCell.dogImageView.image = dogs[indexPath.row].picture
dogCell.dogCreatorButton.titleLabel?.text = dogs[indexPath.row].creator
dogCell.dogVotesLabel.text = "0"
return dogCell
}
}
}
I actually found a solution shortly after writing this question, but I think it might be helpful for others to read.
Because the first indexPath.row is dedicated to a profile cell, I should not have been using the indexPath.row to navigate my dogs array. Instead I should have been using indexPath.row - 1 to get the correct dogs index.
Here's the section I updated:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let profileCell = tableView.dequeueReusableCell(withIdentifier: "profileCell", for: indexPath) as! ProfileTableViewCell
profileCell.nameLabel.text = user.name
profileCell.totalReputationLabel.text = String(describing: user.reputation!)
profileCell.usernameLabel.text = user.username
return profileCell
} else {
let dogCell = tableView.dequeueReusableCell(withIdentifier: "dogCell", for: indexPath) as! DogTableViewCell
dogCell.dogBreedLabel.text = dogs[indexPath.row - 1].breed
dogCell.dogNameLabel.text = dogs[indexPath.row - 1].name
dogCell.dogScoreLabel.text = String(describing: dogs[indexPath.row - 1].score)
dogCell.dogImageView.image = dogs[indexPath.row - 1].picture
dogCell.dogCreatorButton.titleLabel?.text = dogs[indexPath.row - 1].creator
dogCell.dogVotesLabel.text = "0"
return dogCell
}
}

How to iterate through Dictionary of Dictionary Values in UITableViewCell?

This is my first post and I hope its a great question because iv been stuck on this for days. (Literally searched every related question and found nothing that I could add up for a solution.)
Basically I'm building a pure Swift application. My problem is that I cant figure out how to place each dictionary values into each UITableCell that is created.
Also the JSON response from the GET creates a NSCFDictionary type.
UITableViewCell Properties
UILabel - Holds the Offer "name"
UI Label #2 - Holds Offer "description"
UIImage - Holds the Offer "thumb_url"
So basically I need to store each offer object's (name, description, thumb_url) in every UITableViewCell that the ViewController creates.
GET Request
import UIKit
class freeIAPCell: UITableViewCell {
#IBOutlet weak var aName: UILabel!
#IBOutlet weak var aDescription: UILabel!
#IBOutlet weak var aImage: UIImageView!
}
class FreeIAPViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
// Everbadge Request
var apiURL = "apiurlhere"
var parsedArray: [[String:String]] = []
func queryEB() {
// Query DB Here
// Store the API url in a NSURL Object
let nsURL = NSURL(string: apiURL)
let request = NSMutableURLRequest(URL: nsURL!)
request.HTTPMethod = "GET"
// Execute HTTP Request
let task = NSURLSession.sharedSession().dataTaskWithURL(nsURL!) {
data, response, error in
if error != nil {
print("Error = \(error)")
return
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments) as! NSDictionary
print(json.isKindOfClass(NSDictionary)) // true
let data = json.objectForKey("data") as! NSDictionary
//print(data)
let m = data.objectForKey("offers") as! NSArray
print(m)
print(m.valueForKeyPath("name"))
self.parsedArray = m as! [[String : String]]
} catch {
print("THERE WAS AN ERROR PARSING JSON FOR EVERBADGE")
}
}
task.resume()
}
override func viewDidLoad() {
super.viewDidLoad()
queryEB()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
}
// MARK: UITableView method implementation
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("freeAppCell", forIndexPath: indexPath) as! freeIAPCell
let obj = parsedArray[indexPath.row] // fatal error: Index out of range
cell.aName.text = obj["name"]
return cell
}
}
API Request Data Structure (print(m))
(
{
"name" = "Mate";
id = 23941;
description = "10-20 word description goes here"
"url" = "google.com
"ver" = "0.12"
price = "0.17"
"public_name" = "Good Ole Mate"
"thumb_url" = "http://google.com/mate.jpg
};
{
"name" = "Mate";
id = 23941;
description = "10-20 word description goes here"
"url" = "google.com
"ver" = "0.12"
price = "0.17"
"public_name" = "Good Ole Mate"
"thumb_url" = "http://google.com/mate.jpg
};
{
"name" = "Mate";
id = 23941;
description = "10-20 word description goes here"
"url" = "google.com
"ver" = "0.12"
price = "0.17"
"public_name" = "Good Ole Mate"
"thumb_url" = "http://google.com/mate.jpg
};
{
"name" = "Mate";
id = 23941;
description = "10-20 word description goes here"
"url" = "google.com
"ver" = "0.12"
price = "0.17"
"public_name" = "Good Ole Mate"
"thumb_url" = "http://google.com/mate.jpg
};
{
"name" = "Mate";
id = 23941;
description = "10-20 word description goes here"
"url" = "google.com
"ver" = "0.12"
price = "0.17"
"public_name" = "Good Ole Mate"
"thumb_url" = "http://google.com/mate.jpg
};
);
First create public arrays for your 3 items...
var nameArray = [String]()
var descriptionArray = [String]()
var thumbnailArray = [String]()
Then loop through your json parse like this....
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) as! NSDictionary
if responseString != nil
{
let items: AnyObject! = responseString["items"] as AnyObject!
if items != nil
{
// Loop through all search results and keep just the necessary data.
for var i=0; i<items.count; ++i
{
if let names = items[i]["name"] as? NSDictionary
{
let name = names as! String
self.nameArray.append(name)
}
if let descriptions = items[i]["description"] as? NSDictionary
{
let description = descriptions as! String
self.descriptionArray.append(description)
}
if let thumbnails = items[i]["thumb_url"] as? NSDictionary
{
let thumbnail = thumbnails as! String
self.thumbnailArray.append(thumbnail)
}
}
}
self.resultsTableView.reloadData()
Create an OfferTableViewCell Class with a nameLabel:UILabel, descriptionLabel:UILabel, and thumbnailImage:UIImage. Finally in your cellForRowAtIndexPath.....
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("offer", forIndexPath: indexPath) as! OfferTableViewCell
cell.nameLabel.text = self.nameArray[indexPath.row]
cell.descriptionLabel.text = self.descriptionArray[indexPath.row]
let url = NSURL(string: self.thumbnailArray[indexPath.row])
let data = NSData(contentsOfURL: url!)
cell.thumbnailImage.image = UIImage(data: data!)
return cell
}

Resources