I try to load this array out from my save setting "Mybookmarks", and try to write it in a table. That is in the setting =>
[["name" : "apple", "url": "http://www.apple.de"],
["name" : "youtube", "url": "http://www.youtube.de"]]
But it doesn't work, it said always crash. I want to load this kind of array and write it in a tableview.
Any idea on how to fix this so that it can read this from my "var defaults = NSUserDefaults.standardUserDefaults()".
// ViewController.swift
import UIKit
class ViewController: UIViewController,UITableViewDelegate, UITableViewDataSource {
// create references to the items on the storyboard
// so that we can animate their properties
var tableView: UITableView = UITableView()
var objects = []
override func viewDidLoad() {
super.viewDidLoad()
var defaults = NSUserDefaults.standardUserDefaults()
//read
if let testArray : AnyObject? = defaults.objectForKey("Mybookmarks") {
var objects : [NSString] = testArray! as! [NSString]
println("\(testArray)")
}
tableView.frame = CGRectMake(0, 0, 300, view.frame.height);
tableView.delegate = self
tableView.dataSource = self
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.view.addSubview(tableView)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.objects.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
let object = self.objects[indexPath.row]
cell.textLabel?.text = object["name"]!
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("You selected cell #\(indexPath.row)!")
}
}
the type of the array is an array of dictionaries [[String:String]] rather than array of strings [String]
var objects = [[String:String]]()
...
if let testArray : AnyObject? = defaults.objectForKey("Mybookmarks") {
objects = testArray as! [[String:String]]
}
Edit:
and connect the tableview instance in Interface Builder with an IBOutlet.
The instance you're creating with var tableView: UITableView = UITableView() is a brand new instance, it's different from those in IB
nevermind I see that this is not in [String:String]. This must be in let object:
[String:String] = self.objects[indexPath.row]
and now it works
Related
I am successfully downloading and printing data from Realm database. Here is my log:
Item(id: Optional(0), name: Optional("Item (0)"), descr: Optional("Description of item (0)"),
icon: Optional("http://192.168.1.101:8080/api/items/0/icon.png"),
url: Optional("http://192.168.1.101:8080/api/items/0")))
Now I have to assign those values on actual list and I am getting a clean sheet tableview. How to do it properly? I am using .xib as tablewViewCell. I am thankful for any tips.
class ItemRealm : Object {
dynamic var id = 0
dynamic var name = ""
dynamic var desc = ""
dynamic var icon = ""
override class func primaryKey() -> String? {
return "id"
}
}
class ViewController: UIViewController, UITableViewDataSource, UISearchBarDelegate {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var tableView: UITableView!
let realm = try! Realm()
let results = try! Realm().objects(ItemRealm.self).sorted(byKeyPath: "id")
let SERVER_URL = "http://192.168.1.101:8080/api/items"
override func viewDidLoad() {
super.viewDidLoad()
Alamofire.request(SERVER_URL).responseJSON { response in
let items = [Item].from(jsonArray: response.result.value as! [Gloss.JSON])
print(items?[0] as Any)
try! self.realm.write {
for item in items! {
let itemRealm = ItemRealm()
itemRealm.id = item.id!
itemRealm.name = item.name!
itemRealm.desc = item.descr!
itemRealm.icon = item.icon!
self.realm.add(itemRealm)
}
}
_ = self.realm.objects(ItemRealm.self)
// print(items?[0] as Any)
}
// Do any additional setup after loading the view.
tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "TableViewCell")
}
// MARK: - UITableView data source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return results.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as! TableViewCell
var object: ItemRealm
object = self.results[indexPath.row] as ItemRealm
cell.item = object
return cell
}
}
I think you are missing self.tableView.reloadData() after getting data from the response. Consider also assigning fetched data to your results variable.
I am having difficulty getting firebase into my controller. Firebase is working correctly due to me being able to out print to the console. I need to be able to display all data in my app. Please assist!
//
// All.swift
// Guaranteed Pricing
//
import Foundation
import UIKit
import Firebase
class All: UINavigationController, UITableViewDataSource, UITableViewDelegate {
var items: [String] = []
var tableView: UITableView!
let cellIdentifier = "CellIdentifier"
override func viewDidLoad(){
super.viewDidLoad()
self.tableView = UITableView(frame:self.view!.frame)
self.tableView!.delegate = self
self.tableView!.dataSource = self
self.tableView!.registerClass(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
self.view?.addSubview(self.tableView)
let ref = Firebase(url:"https://sizzling-inferno-451.firebaseio.com/services")
ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
for child in snapshot.children {
// let key = child.key //returns -Jikaijsipaij and -kalksdokoas
// let name = child.value.objectForKey("service_name") as NSString?
////
// self.items.append(key)
}
// do some stuff once
print(snapshot.value)
// get these values and put them in the cell's text view. key is more important
print(snapshot.key)
// add to the array and just this array
self.tableView!.reloadData()
})
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
// Fetch Fruit
let fruit = items[indexPath.row]
// Configure Cell
cell.textLabel?.text = fruit
return cell
}
// onclick printing
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print(items[indexPath.row])
}
}
Here's a quick snippet to populate an array within a block, and then once populated reload the tableview to display the data.
user_id_0
name: "Fred"
friend: "Barney"
And the code to read in all of the users, iterate over them and extract each name and add it to an array:
var namesArray: [String] = []
ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
for child in snapshot.children {
let name = child.value["name"] as! String
namesArray.append(name)
}
self.myTableView.reloadData()
})
I have created a UITableView and a UITableVIewCell in Main.storyboard and set it's dataSource and delegate to ViewController .Why UITableView didn't display texts when I run the code.
Another question is that does UITableView load before ViewLoad? If not why in func didRecieveResults() the Array of tableData can achieve datas but in func tableView() it was nil
The whole codes as following
import UIKit
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,HttpProtocol {
#IBOutlet weak var tv: UITableView!
#IBOutlet weak var iv: UIImageView!
#IBOutlet weak var playTime: UILabel!
#IBOutlet weak var progressView: UIProgressView!
var eHttp:HttpController = HttpController()
var tableData:NSArray = NSArray()
var channelData:NSArray = NSArray()
override func viewDidLoad() {
super.viewDidLoad()
eHttp.delegate = self
eHttp.onSearch("http://www.douban.com/j/app/radio/channels")
eHttp.onSearch("http://douban.fm/j/mine/playlist?channel=0")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
println("tableData.count:\(channelData)")
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell!{
let cell = UITableViewCell(style:UITableViewCellStyle.Subtitle,reuseIdentifier:"douban")
let rowData:NSDictionary = self.tableData[indexPath.row] as! NSDictionary
cell.textLabel!.text = "hehehehe"//rowData["title"] as! String
cell.detailTextLabel!.text = "adasdasda"//rowData["artist"] as! String
return cell
}
func didRecieveResults(results:NSDictionary){
if (results["song"] != nil){
self.tableData = results["song"] as! NSArray
println(tableData)
}else if (results["channels"] != nil){
self.channelData = results["channels"] as! NSArray
// println(channelData)
}
}
}
As Lukas points out, you need to return the UITableViewCell at the end of the method.
In fact, what you posted shouldn't even compile, so I'm wondering if you posted your sample code incorrectly.
The first thing to try, and actually return the cell, update your code to:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell!
{
let cell = UITableViewCell(style:UITableViewCellStyle.Subtitle,reuseIdentifier:"douban")
let rowData:NSDictionary = self.tableData[indexPath.row] as! NSDictionary
cell.textLabel!.text = "hehehehe"//rowData["title"] as! String
cell.detailTextLabel!.text = "adasdasda"//rowData["artist"] as! String
// YOU ARE MISSING THIS LINE
return cell
}
Also ensure that you UITableViewDatasource is set properly, and that the required methods are functioning. Specifically, both numberOfRowsInSection and numberOfSectionsInTableView need to be returning values greater than 0. (In the code you posted, you are missing numberOfSectionsInTableView)
As Lukas said in a comment, you should make sure you return a value from your cellForRowAtIndexPath method otherwise it will refuse to build. If you've done that and you still don't see any cells, it's probably because either numberOfRowsInSection or numberOfSectionsInTableView are returning 0, so you should make sure they return a positive integer.
I have a 2D Array which I want to populate in UITableView Custom Cell in a specific pattern.
//Retrieved from Parse backend
var myArray = [["Name1", "Age1"],["Name2", "Age2"],["Name3", "Age3"]]
//What I need is:
nameArray = ["Name1", "Name2", "Name3"]
ageArray = ["Age1", "Age2", "Age3]
So that I can use indexPath to fill the Name data in the custom UITableView cell For Ex: nameArray[indexPath.row]
I tried using the for in loop,
var nameArray = NSMutableArray()
var ageArray = NSMutableArray()
//Inside CellForRowAtIndexPath
for data in myArray {
self.nameArray.addObject(data[0])
self.ageArray.addObject(data[1])
}
cell.nameLabel.text = "\(nameArray[indexPath.row])"
cell.ageLabel.text = "\(ageArray[indexPath.row])"
But I am getting repetitive name and age label filled with Name1 and Age1 in both the cell. Does anyone know whats wrong in this?
Is there a better way to reload this data as needed?
// UPDATED FULL WORKING CODE Thanks to #l00phole who helped me solve the problem
class NewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableView: UITableView!
var data = [[String]]()
var cost = Double()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
uploadData()
}
func uploadData() {
let query = PFQuery(className:"Booking")
query.getObjectInBackgroundWithId("X0aRnKMAM2") {
(orders: PFObject?, error: NSError?) -> Void in
if error == nil && orders != nil {
self.data = (orders?.objectForKey("orderDetails"))! as! [[String]]
//[["Vicky","21"],["Luke", "18"],["7253.58"]]
//*****Removing the last element as it is not needed in the tableView data
let count = self.data.count - 1
let c = self.data.removeAtIndex(count)
cost = Double(c[0])!
//******
} else {
print(error)
}
self.reloadTableData()
}
}
func reloadTableData()
{
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
return
})
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return data.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:NewTableViewCell = self.tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! NewTableViewCell
// Configure the cell...
cell.nameLabel.text = "\(data[indexPath.row][0])"
cell.ageLabel.text = "\(data[indexPath.row][1])"
return cell
}
You are adding to the nameArray and ageArray every time cellForRowAtIndexPath is called and you are not clearing them first. This seems inefficient and you should only populate those arrays when the input data changes, not when generating the cells.
I don't even think you need those arrays, as you could just do:
cell.nameLabel.text = "\(data[indexPath.row][0])"
cell.ageLabel.text = "\(data[indexPath.row][1])"
You don't have to create separate array for name and age, you can use the existing myArray as below
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:NewTableViewCell = self.tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! NewTableViewCell
// Configure the cell...
let dataArray = myArray[indexPath.row]
cell.nameLabel.text = "\(dataArray[0])"
cell.ageLabel.text = "\(dataArray[1])"
return cell
}
}
My Code:
import UIKit
class HomeVCHome: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var usernameLabel: UILabel!
#IBOutlet weak var tableView: UITableView!
var names: [String] = []
var contacts: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self;
self.tableView.dataSource = self;
let url=NSURL(string:"http://mysite/json.aspx")!
let allContactsData=NSData(contentsOfURL:url)
var allContacts: AnyObject! = NSJSONSerialization.JSONObjectWithData(allContactsData!, options: NSJSONReadingOptions(0), error: nil)
if let json = allContacts as? Array<AnyObject> {
print(json)
for index in 0...json.count-1 {
let contact : AnyObject? = json[index]
print(contact)
let collection = contact! as Dictionary<String, AnyObject>
print(collection)
print(collection["name"])
let name : AnyObject? = collection["name"]
let cont : AnyObject? = collection["cont"]
names.append(name as String)
contacts.append(cont as String)
}
}
println(names)
println(contacts)
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.names.count;
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("You selected name : "+names[indexPath.row])
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
var cell = tableView.dequeueReusableCellWithIdentifier("cell") as? UITableViewCell
println("ok 1")
if !(cell != nil) {
cell = UITableViewCell(style: .Subtitle, reuseIdentifier: "cell")
}
println("ok 2")
cell?.textLabel.text=self.names[indexPath.row]
cell?.detailTextLabel?.text = self.contacts[indexPath.row]
println("ok 3")
return cell!
}
}
i try to run, and i can't see my data in tableView... just blank in table View
and i try another code but the same result (table view blank)...
what should i do? i don't know its my mistake code or my simulator have problems like that...
pls change the method and try:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier(simpleTableIdentifier) as UITableViewCell
cell.textLabel.text=self.names[indexPath.row]
cell.detailTextLabel?.text = self.contacts[indexPath.row]
return cell
}