i have a problem with appending an array, you can see my code, i checked the problem's line by: self.items.append(....)
the array is not appended and stay empty.
here is my code:
//
// ViewController.swift
// firer
//
// Created by mike matta on 06/01/2016.
// Copyright © 2016 Mikha Matta. All rights reserved.
//
import UIKit
import Firebase
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var showdatA: UILabel!
#IBOutlet weak var tableView: UITableView!
var items:[String] = []
var userFNAME:String = ""
var userDOB:String = ""
let textCellIdentifier = "TextCell"
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
// Do any additional setup after loading the view, typically from a nib.
///////////
let UsersChannel = Firebase(url: "https://MYFIREBASE.firebaseio.com/users")
UsersChannel.observeEventType(.ChildAdded, withBlock: { snapshot in
if let az = String?((snapshot.value.objectForKey("full_name"))! as! String) {
self.userFNAME = az
}
if let az2 = String?((snapshot.value.objectForKey("dob"))! as! String) {
self.userDOB = az2
}
print("\(self.userFNAME) - \(self.userDOB)")
self.items.append(self.userFNAME) // heeereeee what i am trying to doooooooo
})
// print(self.items)
}
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 items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as UITableViewCell
let row = indexPath.row
cell.textLabel?.text = items[row]
return cell
}
// MARK: UITableViewDelegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
print(items[row])
}
}
i tryed to put the array definition inside the viewdidload() it works...but i need it outside it (like my code)..
i tryed to put the array outside the async block too...still not appending....any one ?
I think that your code works !
The question is :
Why do you think that your array is still empty ?
You have to think the order that your instructions are executed.
At this line :
// print(self.items);
Your array is still empty because the closure is not yet called.
Put this line just after the append and you will see.
And, Just add self.tableView.reloadData() after your append and you will be happy :)
(It will say to your tableview to recall the delegate methods (numberOfRowsInSection ...) )
Related
I have a program written in Swift 3, that grabs JSON from a REST api and appends it to a table view.
Right now, I'm having troubles with getting it to print in my Tableview, but it does however understand my count function.
So, I guess my data is here, but it just doesn't return them correctly:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, HomeModelProtocal {
#IBOutlet weak var listTableView: UITableView!
func itemsDownloaded(items: NSArray) {
feedItems = items
self.listTableView.reloadData()
}
var feedItems: NSArray = NSArray()
var selectedLocation : Parsexml = Parsexml()
override func viewDidLoad() {
super.viewDidLoad()
self.listTableView.delegate = self
self.listTableView.dataSource = self
let homeModel = HomeModel()
homeModel.delegate = self
homeModel.downloadItems()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier: String = "BasicCell"
let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
let item: Parsexml = feedItems[indexPath.row] as! Parsexml
myCell.textLabel!.text = item.title
return myCell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return feedItems.count
}
override func viewDidAppear(_ animated: Bool) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Are you by any chance able to see the error that I can't see?
Note. I have not added any textlabel to the tablerow, but I guess that there shouldn't be added one, when its custom?
Try this code:
override func viewDidLoad() {
super.viewDidLoad()
print(yourArrayName.count) // in your case it should be like this print(feedItems.count)
}
I'm trying to create an app that displays some data on labels on the top of a screen, and then the lower half or so is a table which will allow selection of an item in the table to pop up another segue for editing a value. I'm struggling though to get the didSelectRowAtIndexPath to be called when an item on the list is selected by the user. I've put the code for the View controller below.
I've searched quite a bit and haven't found anything so far that explains the issue I'm seeing.
I think I've connected everything up correctly as far as delegates and datasource, and I'm not using any gesture captures so it's not those. Does anyone have any ideas?
I've attached screen grabs of the view controller connections and attributes inspector settings as well.
Connections screengrab
Attributes screengrab
import UIKit
class TemperatureViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var CurrentTemp: UILabel!
#IBOutlet weak var HeaterStatus: UILabel!
#IBOutlet weak var ChillerStatus: UILabel!
#IBOutlet weak var TempTableView: UITableView!
var settings = [TemperatureSettings] ()
var HeaterTemp:Float = 0.0
var ChillerTemp:Float = 0.0
var ThresholdTemp:Float = 0.0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.loadTempSettings()
TempTableView.delegate = self
TempTableView.dataSource = self
TempTableView.allowsSelection = true
TempTableView.editing = false
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.loadTempSettings()
}
func loadTempSettings() {
let TempSetting1 = TemperatureSettings(name: "Heater On at", CurrentSetting: HeaterTemp)!
let TempSetting2 = TemperatureSettings(name: "Chiller On at", CurrentSetting: ChillerTemp)!
let TempSetting3 = TemperatureSettings(name: "Threshold", CurrentSetting: ThresholdTemp)!
settings = [TempSetting1, TempSetting2, TempSetting3]
TempTableView.reloadData()
//refreshControl?.endRefreshing()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return settings.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Stop spoof separators after the table entries for blank entries
tableView.tableFooterView = UIView(frame: CGRect.zeroRect)
// Turn off the separator for each cell.
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
let cellIdentifier = "TemperatureSettingsTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TemperatureSettingsTableViewCell
let setting = settings[indexPath.row]
cell.SettingNameLabel.text = setting.name
cell.SettingCurrentLabel.text = String(format: "%.1f C", setting.CurrentSetting)
cell.SettingCurrentLabel.textAlignment = .Left
// Configure the cell...
//useTimer = true
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("Setting Row \(indexPath.row) clicked")
performSegueWithIdentifier("Settings", sender: self)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This works for me:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("works");
}
Add override before func maybe?
I have figured out how to pass data between views with delegates in other situations but this one is stumping me.
In this example I am trying to send data resulting from pressing a button, up to the label using a delegate pattern but without any success. My guess is that I am missing something fundamental here and I haven't found any examples that deal with delegates in quite this way.
//
// ViewController.swift
// TableCellDelegate
//
// Created by Chris Cantley on 6/1/15.
// Copyright (c) 2015 Chris Cantley. All rights reserved.
//
import UIKit
class ViewController: UIViewController, CellInfoDelegate {
var cellViewController = CellViewController()
//The place to put the number into.
#IBOutlet weak var sumLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
cellViewController.delegate = self
}
//2)...to here.
func processThatNumber(theNumber: Int) {
println("out : \(theNumber)")
}
}
// Table View delegates
extension ViewController: UITableViewDataSource, UITableViewDelegate
{
//One row
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
// Load custom cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("thisCustomCell", forIndexPath: indexPath) as! CellViewController
return cell
}
}
//-------------------- Protocol for Delegate -----------------------
protocol CellInfoDelegate {
func processThatNumber(theNumber: Int)
}
//-------------------- Cell to Pass info to Parent -----------------------
class CellViewController: UITableViewCell{
var sumNumber: Int = 0
var delegate: CellInfoDelegate?
#IBAction func addButton(sender: AnyObject) {
// increment that number
self.sumNumber += 5
//1) I want to get it from here...... but delegate ends up nil
if let delegate = self.delegate {
delegate.processThatNumber(self.sumNumber)
}
//Shows that the number is incrementing
println(sumNumber)
}
}
The ViewController and CellViewController are connected to their respective classes
Thanks in advance.
You should set the delegate here:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("thisCustomCell", forIndexPath: indexPath) as! CellViewController
cell.delegate = self // <-- Set the delegate.
return cell
}
Thanks to i_am_jorf for the solution, here is the code that works.
//
// ViewController.swift
// TableCellDelegate
//
// Created by Chris Cantley on 6/1/15.
// Copyright (c) 2015 Chris Cantley. All rights reserved.
//
import UIKit
import Foundation
class ViewController: UIViewController, CellInfoDelegate {
//The place to put the number into.
#IBOutlet weak var sumLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
//2)...to here.
func processThatNumber(theNumber: Int) {
println("out : \(theNumber)")
self.sumLabel.text = toString(theNumber) as String
}
}
// Table View delegates
extension ViewController: UITableViewDataSource, UITableViewDelegate
{
//One row
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
// Load custom cell
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("thisCustomCell", forIndexPath: indexPath) as! CellViewController
//SOLUTION : put the Delgate HERE in the place where the cell is instantiated so that there is a connection back
// to this class from the Cell class
cell.delegate = self
return cell
}
}
//-------------------- Protocol for Delegate -----------------------
protocol CellInfoDelegate {
func processThatNumber(theNumber: Int)
}
//-------------------- Cell to Pass info to Parent -----------------------
class CellViewController: UITableViewCell{
var sumNumber: Int = 0
var delegate: CellInfoDelegate?
#IBAction func addButton(sender: AnyObject) {
// increment that number
self.sumNumber += 5
//1) I want to get it from here...... but delegate ends up nil
if let delegate = self.delegate {
delegate.processThatNumber(self.sumNumber)
}
//Shows that the number is incrementing
println(sumNumber)
}
}
Do you need to use Delegates?
What if you have this function output a number:
func processThatNumber(theNumber: Int) -> Int {
println("out : \(theNumber)")
return theNumber
}
Then set the text on the label using the button:
#IBAction func addButton(sender: AnyObject) {
self.sumNumber += 5
sumLabel.text = "\(processThatNumber(self.sumNumber))"
println(sumNumber)
}
Would that work for you?
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let path = NSBundle.mainBundle().pathForResource("TableRowInfo", ofType: "plist")!
let dict = NSDictionary(contentsOfFile:path)!
var artists: AnyObject = dict.objectForKey("Artist")!
var stages: AnyObject = dict.objectForKey("Stage")!
println(artists)
println(stages)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return artists.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("InfoCell", forIndexPath: indexPath) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: .Subtitle, reuseIdentifier: "InfoCell")
cell!.accessoryType = .DisclosureIndicator
}
return cell!
}
}
Hey all,
I'm new to swift so just experimenting with some things. What I'm trying to do is filling my table with content from a plist file. I know this isn't the best way! I already loaded the list successfully. My println(artists) returns what I want as well does the stages. The only problem is if I call artists or stages outside my viewDidLoad function it doesn't work. Why is that and how do I solve it?
Thanks in advance.
Greets,
Wouter
The variables "artists" and "stages" do not exists outside of the viewDidLoad-Function scope. You have to define them as properties to access them outside of the viewDidLoad-function. Like this
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var artists: AnyObject?
var stages: AnyObject?
override func viewDidLoad() {
...
artists: AnyObject = dict.objectForKey("Artist")
...
}
I'm trying to make a view controller that has one text field that populates the tableview below, ideally the user will be able to continue to add to the tableview without jumping between two views.
I previously had it working with the text field on one view that populates a UITableView and used prepareForSegue to push the data to the table, but I haven't been able to get it to work with just one view.
Can anyone please point out where I'm going wrong or push me to a tutorial / documentation to help?
Edit: Clarity
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate {
#IBOutlet var tableView: UITableView!
#IBOutlet weak var textField: UITextField!
var items: [String] = ["Pls", "work", "pls", "work", "pls"]
var foodGroup: FoodGroup = FoodGroup(itemName:"")
//var foodGroup: [FoodGroup] = []
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel.text = self.items[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("Selected cell #\(indexPath)")
}
func addFood(sender: AnyObject!) {
if (countElements(self.textField.text) > 0) {
self.foodGroup = FoodGroup(itemName: self.textField.text)
}
}
#IBAction func addFoodToList() {
let source = FoodGroup
let foodGroup:FoodGroup = source.foodGroup
if foodGroup.itemName != "" {
self.foodGroup.append(foodGroup)
self.tableView.reloadData()
}
}
}
It seems like your intention here is to have your dataSource be an array of FoodGroup objects. If this is indeed the case you can get rid of your foodGroup instance variable and update your items definition to be like so:
var items = [FoodGroup]()
then in addFoodToList:
if self.textField.text != "" {
let foodGroup = FoodGroup(itemName: self.textField.text)
self.items.append(foodGroup)
self.tableView.reloadData()
}
and finally in cellForRowAtIndexPath:
var cell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
let foodGroup = self.items[indexPath.row] as FoodGroup
cell.textLabel.text = foodGroup.itemName
return cell
Also I don't quite see the intention of your the addFood(sender: AnyObject!) function. Looks like cruft. I would get rid of it. Good luck!