UITableView Data Source - swift

I am receiving 2 errors.
The first I am confused about because everything is inside the {} so I'm not sure where I am going wrong.
"Type 'StoriesViewController' does not conform to protocol
'UITableViewDataSource' Clicking fix adds:
func tableView(_ tableView: UITableView, cellForRowAt indexPath:
IndexPath) -> UITableViewCell {
<#code#>
}
and 2nd error
Ambiguous use of 'dequeueReusableCellWithIdentifier
I assigned the table cell the identifier "storyCell" from the main storyboard
Full code:
// creating a custom color
extension UIColor {
static var darkmodeGray = UIColor.init(red: 41/255, green: 42/255, blue: 47/255, alpha: 1)
}
class StoriesViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
<#code#>
}
#IBOutlet weak var tableView: UITableView!
let storySelection = [("WeekOne"),("WeekTwo"),("WeekThree"),("WeekFour"),("WeekFive"),("WeekSix")]
let storySelectionImages = [UIImage(named: "WeekOne"), UIImage(named: "WeekTwo"), UIImage(named: "WeekThree"), UIImage(named: "WeekFour"), UIImage(named: "WeekFive"), UIImage(named: "WeekSix")]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.view.backgroundColor = UIColor .darkmodeGray
}
//Part One
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
//Part Two
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return storySelection.count
}
//Part Three
private func tableView(tableView :UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell=tableView.dequeueReusableCellWithIdentifier("storyCell", forIndexPath: IndexPath) as! TableViewCell
cell.CoverArt.image=self.storySelectionImages[indexPath .row]
return cell
}
}

Your code is Swift 2(!) code.
The usual way to update the signature of a method is to comment it out, retype it and use code completion.
Or read the documentation, that's always a good idea.
The three methods are (numberOfSections can be omitted if there is only one section)
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return storySelection.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "storyCell", for: indexPath) as! TableViewCell
cell.CoverArt.image = self.storySelectionImages[indexPath.row]
return cell
}

Related

How to get the index of the array from a TableViewCell when executing a contextmenue action

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIContextMenuInteractionDelegate {
#IBOutlet weak var plannerTableView: UITableView!
...
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myPreparedTasks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let task = self.myPreparedTasks[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "taskCell", for: indexPath) as! TaskTableViewCell
cell.taskId?.text = task.id
let interaction = UIContextMenuInteraction(delegate: self)
cell.addInteraction(interaction)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? {
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil, actionProvider: { suggestedActions in
return self.makeContextMenu()
})
}
func makeContextMenu() -> UIMenu {
let add = UIAction(title: "Neuer Task", image: UIImage(systemName: "plus.square")) { action in
// Show the Task ID
}
return UIMenu(title: "Task", children: [add])
}
}
iOS 13, Swift 5
Hi. This is the first time I implement a context menue in a TableViewCell. I do the stuff above.
And it looks great. But I can not get the ID of the myPreparedTasks array from the tableview content.
How can I get this id? Please give me an answer for this construct. I see many other constructs in the net but I don't understand it yet.
Many thanks
Jens
For a context menu in a table view you have to implement the delegate method
optional func tableView(_ tableView: UITableView,
contextMenuConfigurationForRowAt indexPath: IndexPath,
point: CGPoint) -> UIContextMenuConfiguration?
rather than adding an UIContextMenuInteraction to each cell.

Inserting a table view row data from another table view?

So I have two table views. MainTableView and SecondaryTableView, The MainTableView has empty rows with no text. A Table view cell is configured though. These rows have the option to delete. The SecondaryTableView rows also have an editing style in which I am using to ADD the selected row into the MainTableView rows.
class MainVC: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet var mycartableview: UITableView!
var passedcar = String()
override func viewDidLoad() {
super.viewDidLoad()
mycartableview.tableFooterView = UIView(frame: CGRect.zero)
}
var diynames: [String] = ["a","b","c"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return diynames.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let diyname = diynames[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "mycarcell") as! mycarcell
cell.mycartitle.text = diyname
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
diynames.remove(at: indexPath.row)
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
}
SecondaryVC code:
class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource{
let names = ["aa","ba","ca","da","ea",]
#IBOutlet var tableview: UITableView!
#IBOutlet var slctedcar: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.tableview.backgroundColor = .white
// Do any additional setup after loading the view.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
return names.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "diylistcell") as! diylistcellTableViewCell
cell.diytitle.text = names[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let addbutton = UITableViewRowAction(style: .normal, title: "Add") { (rowAction, indexpath
) in
print("Add clicked")
let mycarvc = MyCarViewController()
mycarvc.diynames.append(contentsOf: self.hcdiynames)
let hcindexpath = IndexPath(row: mycarvc.diynames.count - 1, section: 0)
mycarvc.mycartableview.insertRows(at: [hcindexpath], with: .automatic) //this is where the error occurs. Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
mycarvc.mycartableview.endUpdates()
}
addbutton.backgroundColor = UIColor.darkGray
return [addbutton]
}
Clear Image of Error
That's where my pain is coming from. As you could see in the picture above the highlighted area it says that my array coming from the main vc is a count of 8. That checks out completely because the original array has 3 and I am appending 5 new ones. The error implicitly found nil has left me clueless in this scenario. If anybody has any suggestions on how to fix this problem it would be highly appreciated, thank you .
This is a common error when you try to transfer data between VC , I usually create 1 variable which will store what I want and after in the viewDidLoad() I give the value of this variable to what I really want , IN your code the equivalent is
class MainVC: UIViewController,UITableViewDataSource,UITableViewDelegate {
#IBOutlet var mycartableview: UITableView!
var passedcar = String()
// I JUST CREATED THE VARIABLE WHICH WILL HOLD OUR VALUES
var diynamesContainer = [String]()
///////////////////
var diynames: [String] = ["a","b","c"]
override func viewDidLoad() {
super.viewDidLoad()
mycartableview.tableFooterView = UIView(frame: CGRect.zero)
// I ADD TO OUR ARRAY THE VALUE OF THE diynamesContainer
diynames.append(contentsOf: diynamesContainer)
//////////////////
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return diynames.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let diyname = diynames[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "mycarcell") as! mycarcell
cell.mycartitle.text = diyname
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
diynames.remove(at: indexPath.row)
tableView.beginUpdates()
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.endUpdates()
}
}
/*
// MARK: - Navigation
and in our main vc you replace
let mycarvc = MyCarViewController()
mycarvc.diynames.append(contentsOf: self.hcdiynames)
by
let mycarvc = MyCarViewController()
mycarvc.diynamesContainer = self.hcdiynames
Try to run your code, the error will go away

TableView Rendering?

I have a table view that is rendering some static data into a UITableView but occasionally when running on a physical device the data is replaced with ? (see screenshot). I have listed the code below if anyone has an idea why this is occurring?
Here is the code for the table view
import UIKit
class OvenViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
extension OvenViewController : UITableViewDataSource,UITableViewDelegate{
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return GridData.ovenTempConvArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: OvenCell.className, for: indexPath) as! OvenCell
let data = GridData.ovenTempConvArray[indexPath.row]
cell.lblFTemp.text = "\(data["f"] ?? "") F"
cell.lblCTemp.text = "\(data["c"] ?? "") C"
cell.lblGasMark.text = data["gm"]
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}

UITABLE view sections with different prototype cells in each section

I have a table view with different sections and for each section it has different prototype cells. I have created the prototype cell in storyboard but I could not make more than one cell in cellForRowAtIndexPath. I have attached the whole code for reference.
This is my storyboard design
This is the final output screen which it should look like
import UIKit
class PlacePeopleViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var friendlistTableView: UITableView!
var sectionHead = ["Friends", "Others"]
override func viewDidLoad() {
super.viewDidLoad()
friendlistTableView.delegate = self
friendlistTableView.dataSource = self
// Do any additional setup after loading the view.
}
// MARK: - tableview datasource & delegate
func numberOfSections(in tableView: UITableView) -> Int {
return sectionHead.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return self.sectionHead[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 5
}else {
return 10
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! RecentVizzTableViewCell
cell.placeName.text = "poland"
cell.placeAddress.text = "Simon Albania"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 79
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 15
}
}
Note : You can do this using only one cell. just hide/show the connect Button by checking some condition.
If you want to use different cells for different sections, inside your cellForRowAt indexPath method return your cells based on your section like below .
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1") as! RecentVizzTableViewCellOne
return cell
default:
let defaultcell = tableView.dequeueReusableCell(withIdentifier: "defaultcell") as! RecentVizzTableViewCellDefatult
return defaultcell
}
hope this will help to you. good luck.

UITableView only displays one section

I have a UITableView that is supposed to have items in sections but only the first section (Science) in the array is appearing and I'm not sure what's wrong with it. It should be displaying both sections.
My code:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet weak var tableView: UITableView!
var checked = [Bool]()
let section = ["Science", "Math"]
let items = [["Physics", "Biology", "Chemistry"], ["Algebra I", "Algebra II", "Statistics"]]
override func viewDidLoad(){
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.tableView.allowsMultipleSelection = true
}
override func didReceiveMemoryWarning(){
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return self.items[section].count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int{
// #warning Incomplete implementation, return the number of sections
return self.section.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
return self.section[section]
}
//All before.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = self.items[indexPath.section][indexPath.row]
//MARK: -Checkmark and save support.
cell.accessoryType = cell.isSelected ? .checkmark : .none
cell.selectionStyle = .none // to prevent cells from being "highlighted"
return cell
}
//MARK: - Checkmark and save functions.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
//MARK: - Sections
}
You made a mistake, wrong method. Let change numberOfSectionsInTableView(tableView:) to:
func numberOfSections(in tableView: UITableView) -> Int {
return self.section.count
}
In ViewDidLoad :
tableView.delegate = self
tableView.dataSource = self