I am trying to use tableview with delegate methods.
But it is not working.
My class:
class IsteklerTVVC: UITableViewController {
#IBOutlet var mainTable: UITableView!
let missionControl = MissionControl.sharedInstance
var yardimList:[YardimIstek] = [YardimIstek]()
override func viewDidLoad() {
super.viewDidLoad()
mainTable.delegate=self
mainTable.dataSource=self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
veriGetir()
}
func veriGetir() {
let parameters: Parameters = [
"uid": missionControl.id
]
Alamofire.request("domain.com", method: .post, parameters: parameters).responseJSON { response in
print("istek eklendi \(parameters)")
let json = JSON(response.result.value)
for (key,subJson):(String, JSON) in json {
print(subJson[0]["tarih"].string)
let blok=YardimIstek()
blok.id=0
blok.isim="Name"
blok.tarih=subJson[0]["tarih"].string!
blok.lat=subJson[0]["lat"].string!
blok.long=subJson[0]["long"].string!
self.yardimList.append(blok)
}
DispatchQueue.main.async {
self.mainTable.reloadData()
print("ok \(self.yardimList.count)")
}
}
}
let textCellIdentifier = "mainCell"
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yardimList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: isteklerCell = tableView.dequeueReusableCell(withIdentifier: textCellIdentifier) as! isteklerCell
let row = indexPath.row
let blok=yardimList[row]
cell.setCell(blok: blok)
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
}
class isteklerCell: UITableViewCell {
#IBOutlet weak var isimSoyisim: UILabel!
#IBOutlet weak var zaman: UILabel!
func setCell(blok: YardimIstek) {
isimSoyisim.text=blok.isim
zaman.text=blok.tarih
}
}
The problem is, no delegate methods are getting called. I think there is a problem with names. Because when I was using Swift 2, I used the tableview's outlet name as "tableView" and it was working well. Now Swift 3 is not allowing that naming.
So my tableview is looking empty even there is data in yardimList dictionary.
How can I resolve this?
Your delegate function signatures are wrong. They were updated with swift 3:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
Two things to check:
First one is do you need the mainTable property? UITableViewControllers comes with a UITableView property called tableView. If you don't need 'mainTable', you can just replace it with tableView.
Second, if you do need mainTable, then you need to make sure you connected the #IBOutlet to the UITableView you want to use.
Related
i have a tableview in a viewcontroller and because i need to reuse most of the code for another table i created an extra class:
class StatisticsViewDelegate: NSObject, UITableViewDelegate, UITableViewDataSource {
var defaultList:[String]
var infolist:[String] = []
var tableView:UITableView
var controller:UIViewController?
init(defaultList:[String], view:UITableView, controller:UIViewController?) {
self.defaultList = defaultList
self.controller = controller
tableView = view
super.init()
tableView.delegate = self
tableView.dataSource = self
loadTable()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return infolist.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "infocell", for: indexPath) as! TableViewCell
// [fill cell]
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// [...]
}
func loadTable() {
DispatchQueue.global(qos: .userInitiated).async {
//[...]
// in this case:
self.infolist = self.defaultList
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
and in my UITViewController in the viewDidLoad():
delegate = StatisticsViewDelegate(defaultList: defaultList, view: tableView, controller:self)
delegate is a member of the ViewController
now when i run it, the function func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) never gets called. The func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) gets called however(before and after the reload) and returns the correct number(in my case 4). The TableView isn't visible at all. Where is my error?
Maybe you can use the subclassing strategy to resolve your problem. There are many reference passed to your class and if you forgot to clean that up you will be have memory leaks in your hand. So I'll suggest the simple example as below. You can modify as you like and let me know if that was what you are after. If not please pardon me.
//This will be parent class that will handle all table methods, so you need to write only once the delegates and stuffs
class MyCommonTableController: UITableViewController {
var infoList = [String]()
// MARK: - TableView Delegate and Datsource Impl
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return infoList.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 55.0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = infoList[indexPath.row]
return cell
}
}
The first class that is directly subclassing the from above MyCommonTableController
//In here we just have to know the data and set the infoList from parent
class TheTableViewController: MyCommonTableController {
let defaultList = ["Data1","Data2","Data3"] //....etc
override func viewDidLoad() {
super.viewDidLoad()
//this is were I will set those
infoList = defaultList
//reload the table
tableView.reloadData()
}
}
The second class that is directly subclassing the from above MyCommonTableController. Same process goes here
class TheSecondTableViewController: MyCommonTableController {
let defaultList = ["List1","List2","List3"] //....etc
override func viewDidLoad() {
super.viewDidLoad()
//this is were I will set those
infoList = defaultList
//reload the table
tableView.reloadData()
}
}
And now you are not repeating and table methods. You can also get the reference of table and use in your norma table view
#IBOutlet weak var theTable: UITableView!
let defaultList = ["List1","List2","List3"] //....etc
let commonTable = MyCommonTableController()
// MARK: - LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
commonTable.infoList = defaultList
commonTable.tableView = theTable
}
Here is the code from my custom cell class:
import UIKit
class CustomOrderTableViewCell: UITableViewCell {
#IBOutlet var MealName: UILabel!
#IBOutlet var MealPrice: UILabel!
#IBOutlet var MealDescription: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func deleteMeal(sender: AnyObject) {
}
}
Here are the table view related functions:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mealArray.orderedMeals.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
print("in")
var cell = tableView.dequeueReusableCellWithIdentifier("orderCell", forIndexPath: indexPath) as! CustomOrderTableViewCell
cell.MealName.text = mealArray.orderedMeals[indexPath.row].mealName
cell.MealDescription.text = mealArray.orderedMeals[indexPath.row].mealDescription
let price = NSString(format: "%.2f", mealArray.orderedMeals[indexPath.row].mealPrice) as String
cell.MealPrice.text = "R" + price
return cell
}
The problem is that nothing gets displayed in the table view and func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell is never called.
Any solutions? Thanks
If func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell is never called that means you have not connected your UITableViewDataSource in IB correctly. Make sure that you connect the dataSource property with your ViewController. Also check that all classes are set for your ViewController, TableView and the Cell itself as this another common mistake.
I want to put the string from whichever cell is chosen (part of the arrat basicPhrases) into a variable (selectedBPhrase) then I want to perform the segue BasicPhrases2Phrase and have it display the string by itself. How do I do that? I'm pretty sure it has something to do with using didSelectRowAtIndexPath but I'm not sure.
This is my code:
import UIKit
class BasicPhrases: UITableViewController {
let basicPhrases = ["Hello.","Goodbye.","Yes.","No.","I don't understand.","Please?","Thank you.","I don't know."]
var selectedBPhrase = ""
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return basicPhrases.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell")!
cell.textLabel?.text = basicPhrases[indexPath.row]
return cell
}
I think it's in here but not sure.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("BasicPhrases2Phrase", sender: self)
}
}
Thanks for any help in advance.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
selectedBPhrase = basicPhrases[indexPath.row]
performSegueWithIdentifier("BasicPhrases2Phrase", sender: self)
}
You need to get UIViewTableCell from indexPath, as in cellForRowAtIndexPath, as in didSelectRowAtIndexPath.
For a project, I've three UITableViews in an UITabbarController. The initial view loads the tableview correctly, but when I tap on the second tab, the table loads the right amount of cells and the right cell class, but don't show the content on it.
I logged the method tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) and every cell gets the right string values.
This is the code I use:
import UIKit
import RealmSwift
class Hapjes: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tabel: UITableView!
let realm = try! Realm()
let productArray = try! Realm().objects(Product).filter("categorie = 1")
override func viewDidLoad() {
super.viewDidLoad()
tabel.dataSource = self
tabel.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Hapjes"
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return productArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ProductenCellHapjes", forIndexPath: indexPath) as! ProductenCell
var object = productArray[indexPath.row]
cell.label.text = object.valueForKey("productNaam") as! String
cell.plaatje.image = UIImage(named: "1449032338_news.png")
let tmp = object.valueForKey("productNaam") as! String
print("Hapje: \(tmp)")
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
}
ProductenCell.swift:
import UIKit
class ProductenCell: UITableViewCell {
#IBOutlet weak var plaatje: UIImageView!
#IBOutlet weak var label: UILabel!
}
This is the screenshot of the UI how it goes now:
http://i.stack.imgur.com/Gx0Jw.png
Thanks for your help.
I'm trying to create a table as the main screen of my app and I'm having some issues. I set up the main.storyboard correctly, but there's an override func I have that "doesn't override a superclass". The error is on the nuberOfRowsInSection override func line. Here's my code:
import UIKit
class ViewController: UITableViewController {
var candies = [Candy]()
#IBOutlet weak var editButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup
// after loading the view.
self.candies = [Candy(name: "Jolly Rancher"),Candy(name: "Snickers"),Candy(name: "Twix"),Candy(name: "Butterfinger"),Candy(name: "Milky Way")]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, nuberOfRowsInSection section: Int) -> Int {
return self.candies.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
var candy : Candy
candy = candies [indexPath.row]
cell.textLabel?.text = candy.name
}
#IBAction func editButtonPressed(sender: UIButton) {
editButton.setTitle("Save", forState: UIControlState.Normal)
}
}
Just a guess:
// this should read "numberOfRowsInSection": ~~v
override func tableView(tableView: UITableView, nuberOfRowsInSection section: Int) -> Int {
return self.candies.count
}
As far as I know, UITableViewController does not have a method with a parameter nuberOfRowsInSection, but it does have one with a parameter numberOfRowsInSection.
When dealing with something that isn't working, please start by checking your code for spelling mistakes.
You have a typing mistake. You call the method nuberOfRowsInSection. There is a 'n' missing. The method should be called numberOfRowsInSection.
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.candies.count
}
Also you have en error in your cellForRowAtIndexPath method. You have to return the cell:
return cell