Transfer variables from one class to another class for table view - ios

I am trying to transfer variables from one class into a table view class as follows (excellent code for the table view class).
I get the following error in class SecondViewController:
xnyCats = catRet.mainCats() throws an error Expected Declaration
How do I get class SecondViewController to inherit xnyCats from class XnYCategories?
import UIKit
import Foundation
class XnYCategories {
var catsXny: [String]
init(catsXny: [String]) {
self.catsXny = catsXny
}
func mainCats() -> [String] {
var catsXny = ["Sport", "Recreation", "Travel", "Cultural", "Music"]
return catsXny
}
}
let catRet = XnYCategories(catsXny: [""])
var xnyCats = [""]
xnyCats = catRet.mainCats()
xnyCats[1]
import UIKit
class SecondViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var tableView: UITableView!
#IBAction func displayTapped(sender : AnyObject) {
}
let textCellIdentifier = "TextCell"
let catRet = XnYCategories(catsXny: [""])
var xnyCats = [""]
xnyCats = catRet.mainCats() //throws an error 'Expected Declaration'
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return xnyCats.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 = xnyCats[row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
let row = indexPath.row
println(xnyCats[row] + String(row))
}
}

By checking your code i find out that you are not able to call the mainCats()function from other class so there are different ways to call a function
1: Create the class object and call the function for example
class Demo {
func display() {
println("Hello")
}
}
var d = Demo()
d.display()
2: Declare class function and call it. for example
class Demo {
class func display() {
println("Hello")
}
}
Demo.display()
Now make the following modification in your code and u get the result
class XnYCategories {
var catsXny: [String]
init (catsXny: [String]){
self.catsXny = catsXny
}
class func mainCats() -> [String] {
var catsXny = ["Sport", "Recreation", "Travel", "Cultural", "Music"]
return catsXny
}
}
let catRet = XnYCategories.mainCats()
println(catRet)

Related

How to pass data with delegate from footer cell to view controller?

Ive been stuck trying to pass data from the FoodEatenController(FEC) Footer to the TotalCaloriesController. The code that I have now it shows NOTHING in the calorieLbl of the TotalCalorieController(TCC).
The delegate that ive been using to pass the data from the FEC to the TCC does not pass the text/string data that is in the FoodFooter calorieTotallbl to the TEC calorieLbl
the data that populates the cells of the FEC is retrieved from Cloud Firestore and passed in from anotherView Controller (FoodPickerController)
import UIKit
class FoodEatenController: UIViewController{
var selectedFood: FoodList! // allows data to be passed into the VC
// allows data to be sepearted into sections
var foodItems: [FoodItem] = []
var groupedFoodItems: [String: [FoodItem]] = [:]
var dateSectionTitle: [String] = []
#IBOutlet weak var tableView: UITableView!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? TotalCalorieController {
}
}
}
extension FoodEatenController: UITableViewDelegate, UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return dateSectionTitle.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let date = dateSectionTitle[section]
return groupedFoodItems[date]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let foodCell = tableView.dequeueReusableCell(withIdentifier: "FoodCell") as! FoodCell
let date = dateSectionTitle[indexPath.section]
let foodItemsToDisplay = groupedFoodItems[date]![indexPath.row]
foodCell.configure(withCartItems: fooditemsToDisplay.foodList)
return foodCell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let foodHeader = tableView.dequeueReusableCell(withIdentifier: "FoodHeader") as! FoodHeader
let headerTitle = dateSectionTitle[section]
foodHeader.dateLbl.text = "Date: \(headerTitle)"
return foodHeader
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let foodFooter = tableView.dequeueReusableCell(withIdentifier: "FoodFooter") as! FoodFooter
let date = dateSectionTitle[section]
let arrAllItems = groupedFoodItems[date]!
var total: Float = 0
for item in arrAllItems {
let eaten = item.productList
let selectedMeal = item.foodList.selectedOption
if selectedMeal == 1 {
total = total + (Float(eaten!.calorie))
}
}
foodFooter.calorieTotal.text = String(subtotal!)
foodFooter.delegate = self
return foodFooter
}
}
extension FoodEatenController: EatenFoodDelegate {
func onTouchCaloireInfo(info: String) {
let popUp = self.storyboard?.instantiateViewController(withIdentifier: "AdditionalCostsVC") as! TotalCalorieController
popUp.calorieLbl.text = info
}
}
import UIKit
protocol EatenFoodDelegate: class {
func onTouchCaloireInfo(info: String)
}
class FoodFooter: UITableViewCell {
weak var delegate: EatenFoodDelegate? = nil
#IBOutlet weak var calorieTotal: UILabel!
#IBOutlet weak var totalInfoBtn: UIButton!
#IBAction func totalOnClicked(_ sender: AnyObject) {
self.delegate?. onTouchCaloireInfo(info: calorieTotal.text!)
}
}
class TotalCalorieController: UIViewController, EatenFoodDelegate {
func onTouchCaloireInfo(info: String) {
calorieLbl.text = info
}
#IBOutlet weak var calorieLbl: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func returnButton(_ sender: Any) {
dismiss(animated: true, completion: nil)
print("Close Taxes and Fees")
}
}
Add the following line at the end of the func onTouchCaloireInfo(info:)
self.present(popUp, animated: true, completion: nil)
If you would like to be sure that the function onTouchCaloireInfo(info:) gets called, just add the following line:
debugPrint("onTouchCaloireInfo")
And check, if it prints the given string in the console of the Xcode
extension FoodEatenController: EatenFoodDelegate {
func onTouchCaloireInfo(info: String) {
debugPrint("onTouchCaloireInfo")
let popUp = self.storyboard?.instantiateViewController(withIdentifier: "AdditionalCostsVC") as! TotalCalorieController
self.present(popUp, animated: true) {
popUp.calorieLbl.text = info
}
}
}

How to reload TableVIew Using Model NSObject Class with MVVM

I want to reload TableView without tableview.reloadData() method for that i have used MVVM structure so i have attach model class to storyboard and the issue is that my tableview is reload first and then i get all data how should i solved this issue please help me if any one have a solution !!
This is storyboard model attach
Model Code :-
class MovieModel: Decodable{
var artistName: String = ""
var trackName: String = ""
init(artistName: String, trackName: String){
self.artistName = artistName
self.trackName = trackName
}
}
class ResultModel: Decodable{
var results = [MovieModel]()
init(results: [MovieModel]) {
self.results = results
}
}
My ViewModel File code :-
class MovieViewModel: NSObject {
var artistName: String = ""
var trackName: String = ""
var movieModel: MovieModel?
var movieData = [MovieViewModel]()
override init() {
}
init(movie: MovieModel) {
self.artistName = movie.artistName
self.trackName = movie.trackName
}
func getData(){
Service.shareInstance.getAllMovieData { (movie, error) in
if error == nil{
self.movieData = movie?.map({return MovieViewModel(movie: $0)}) ?? []
print(self.movieData)
}else{
print("\(String(describing: error))")
}
}
}
func numberOfRow(section:Int) -> Int{
return movieData.count
}
func cellForRow(indexPath: IndexPath) -> MovieViewModel{
return self.movieData[indexPath.row]
}
}
My ViewController Code :-
class ViewController: UIViewController {
#IBOutlet var movieVM: MovieViewModel?
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.movieVM?.getData()
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return movieVM?.numberOfRow(section: section) ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
let movie = movieVM?.cellForRow(indexPath: indexPath)
cell?.textLabel?.text = movie?.artistName
cell?.detailTextLabel?.text = movie?.trackName
return cell!
}
}
In my case i am not reload tableview all this is done using ModelClass ! Thank You !!

Gets number of rows but doesn't print

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)
}

In Firebase with Xcode Swift, observeEventType function isn't getting called

I am using the newest version of Firebase and Xcode and Swift 2.0 and i am trying to retrieve data from Firebase but for some reason the function observeEventType isn't ever getting called.
My Dataservice class:
import Foundation
import Firebase
let URL_BASE = FIRDatabase.database().reference()
class DataSevice {
static let ds = DataSevice()
private var _REF_BASE = URL_BASE
private var _REF_POSTS = URL_BASE.child("posts")
private var _REF_USERS = URL_BASE.child("users")
var REF_BASE: FIRDatabaseReference{
return _REF_BASE
}
var REF_POSTS: FIRDatabaseReference{
return _REF_POSTS
}
var REF_USERS: FIRDatabaseReference{
return _REF_USERS
}
func createFirebaseUser(uid: String, user: Dictionary<String, String>){
REF_USERS.childByAppendingPath(uid).setValue(user)
}
}
My FeedVC class where I need to retrieve data:
import UIKit
import Firebase
class FeedVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var tableView: UITableView!
var posts = [Post]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
DataSevice.ds.REF_POSTS.observeEventType(FIRDataEventType.Value, withBlock: { snapshot in
//this is not being called
})
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let post = posts[indexPath.row]
print(post.postCaption)
return tableView.dequeueReusableCellWithIdentifier("PostCell") as! PostCell
}
}

No data is showing up in my UITableView

My IBOutlet for songName is set up correctly, but for some reason
import UIKit
class QueueController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
let testUser = Profile.init(username: "test", followers: [], following: [])
let songOne = Song.init(name: "S1", UWR: testUser.username, genre: "rock", artist: "s1")
var moreSongs = [Song]()
moreSongs = [Song(name: "gah", UWR: testUser.username, genre: "gahh", artist: "GAH")]
Queue.createQueue("2321x", creator: testUser, firstSong: songOne, additionalSongs: moreSongs)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Queue.theQueue!.count
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if let feed = Queue.theQueue {
return feed.count
} else {
return 0
}
}
func songIndex(cellIndex: Int) -> Int {
return tableView.numberOfSections - cellIndex - 1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let song = Queue.theQueue![songIndex(indexPath.section)]
let cell = tableView.dequeueReusableCellWithIdentifier("queueCell", forIndexPath: indexPath) as! QueueCell
//cell.textLabel?.text = song.name this doesnt work also
cell.songName.text = "asdad"
return cell
}
}
For my Queue class:
import UIKit
class Queue {
let creator:Profile!
let planetID:String!
let beginningSong: Song!
var feed:Array<Song>?
static var theQueue:Array<Song>?
init (id:String!, creator:Profile!, firstSong:Song!) {
self.planetID = id
self.creator = creator
self.beginningSong = firstSong
}
func addSong (song: Song) {
feed?.append(song)
}
static func createQueue (id:String!, creator:Profile!, firstSong:Song!, additionalSongs: [Song]) {
let temp = Queue(id: id, creator: creator, firstSong: firstSong)
for song in additionalSongs {
temp.addSong(song)
}
self.theQueue = temp.feed
}
}
Song class:
import UIKit
class Song {
let name:String!
let userWhoRequested:String!
let genre: String?
let artist: String?
init (name:String!, UWR:String!, genre:String?, artist:String?) {
self.name = name
self.userWhoRequested = UWR
self.genre = genre
self.artist = artist
}
}
class QueueCell: UITableViewCell {
#IBOutlet weak var songName:UILabel!
#IBOutlet weak var userPicture:UIImageView!
#IBOutlet weak var isCurrent:UIImageView!
}
The table view displays properly but no data shows up in my controller, and I'm not sure why. The reuse cell identifier is also correct. The data in viewDidLoad() is also in my app delegate's func application.
Thanks!
Your problem is with the feed inside your CreateQueue method, that was never initialized
And change
var feed:Array<Song>?
to
var feed = [Song]()

Resources