Create object that conform to protocol in Swift - swift

I want to create cell that i know, is conformable to specific protocol.
However, when i try to do :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell<ModelBinding> = tableView.dequeueReusableCell(withIdentifier: "VacanciesCell", for: indexPath as IndexPath)
return cell
}
I got an error. How to fix it?

You have to subclass cell , which confirms the protocol that you want to use. Here i have created a sample protocol and CustomCell which confirming the protocol i have created.
1. Sample protocol
protocol MyProtocol {
func protocolMethod()
}
2. Custom subClassed cell
class CustomCell:UITableViewCell,MyProtocol {
//Implementation of Protol method
func protocolMethod() {
}
}
3. Use of that cell on tableview
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:CustomCell = tableView.dequeueReusableCell(withIdentifier: "VacanciesCell", for: indexPath as IndexPath) as! CustomCell
return cell
}

Related

Typecasting with variable

I have an enum that will indicate the identifier and class to use for a tableViewCell.
enum Settings: String {
case Delete = "deleteCell"
var cellType: UITableViewCell.Type {
switch self {
case .Delete: return DeleteCell.self
}
}
}
In my tableView rowForIndexPath I am able to get the cell with the reuseIdendifyer, but it won't recognize the setting object to get the class. The error here is Use of undeclared type 'setting', specifically on the end of the line.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let setting = Settings.enabledSettings[indexPath.row]
return tableView.dequeueReusableCell(withIdentifier: setting.rawValue, for: indexPath) as! setting.cellType
}
It's not bad now with just the one object, but this will be growing soon and it's mostly the same thing, just changing the class name. Is it possible to pull the class type from another source like this so I can keep the rowForIndexPath function short and sweet, or do I need to do something like this?
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let setting = Settings.enabledSettings[indexPath.row]
var cell = tableView.dequeueReusableCell(withIdentifier: setting.rawValue, for: indexPath)
if setting == .Delete { cell = cell as! DeleteCell }
return cell
}

How to add table view cell with a button inside of another table view cell?

I am trying to make a to-do list app and I am having trouble trying to add subtasks to my main to-do tasks. I have a button inside each table view cell, when this button is pressed I want it to add another table view cell that I can type and save a "subtask" on.
//set up tableView row amount
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return taskData.count
}
//set up what is in the tableView row
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//This is for a main task
let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! CustomTableViewCell
cell.label.text = taskData[indexPath.row]
return cell
}
Use delegates to pass data from cells to your ViewController, and reload the tableView.
CustomTableViewCell:
protocol CustomTableViewCellDelegate: class {
func customTableViewCellButtonClicked(_ cell: CustomTableViewCell)
}
class CustomTableViewCell: UITableViewCell {
weak var delegate: CustomTableViewCellDelegate?
func buttonClicked() {
self.delegate?.customTableViewCellButtonClicked(self)
}
}
ViewController:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! CustomTableViewCell
cell.label.text = taskData[indexPath.row]
cell.delegate = self
return cell
}
func customTableViewCellButtonClicked(_ cell: CustomTableViewCell) {
// add the task you need from that cell to your tasks list.
taskData.append(....)
//reload your tableView
self.tableView.reloadData()
}

Nil is returned everytime I try to access textLabel of UITableViewCell

I am trying to get the text of the UITableViewCell in my
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedCell = tableView.cellForRow(at: indexPath)
let cellLabel = selectedCell!.textLabel!.text
print(cellLabel)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let musicCell = music[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "MusicCell") as! MusicCell
cell.setMusic(music: musicCell)
return cell
}
but its returning nill.
MusicListView is my UIViewController and I have extended it
extension MusicListView: UITableViewDataSource, UITableViewDelegate {
}
Any help will be greatly appreciated :)
So as suggested by others I accessed the required data from the data model.
I wrote a little function to access the data model
func findMusic(id : Int) -> String {
currentTitle = songList[id].title!
return currentTitle
}
and called it everytime a user tapped on a cell
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
currentTitle = findMusic(id: indexPath.row)
playSong(title: currentTitle)
}

can't use my function for viewdidload Use of unresolved identifier 'getSegue' swift

cant call func for viewdidload
CODE
Use of unresolved identifier 'getSegue'
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! konuCell
func getSegue() {
cell.dersAdiLabel.text = gelenDersAdi
}
return cell
}
Basically, You written your function in the cellForRowAtIndexPath this will call nested Function but you have to write this at class scope.
In short writegetSegue() function at class level scope just like that:
func getSegue() {
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! konuCell
cell.dersAdiLabel.text = gelenDersAdi
return cell
}
To access getSegue, move it outside the scope of tableView(_:cellForRowAt:), e.g.:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
[...]
}
func getSegue() {
[...]
}
...but since getSegue would require a cell that it can modify, this is not going to work the way you want. I'd suggest keeping the code in cellForRowAt and reload the table view in viewDidLoad.

code in cellForRowAt be called after code in cell's class

I have a question about the order of code execute with cellForRowAt
This is my cellForRowAt function
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MyTableViewCell
print(1)
return cell
}
This is my code in my MyTableViewCell.swift
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
print(2)
}
When I run my code. The console log print this result
2
1
So, my code in my cell's class run before code in cellForRowAt.
But, I want my code in my cell's class run after code in cellForRowAt.
I want the result like this:
1
2
How can I do like that?
in your MyTableViewCell.swift add a function:
func doMyStuff() {
print(2)
}
back again to your cellForRowAtIndexPath:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MyTableViewCell
print(1)
cell.doMyStuff()
return cell
}
Try to do that stuff not in the init function, but in the awakeFromNib
override func awakeFromNib(){
super.awakeFromNib()
//stuff
}
You can create a custom cell class with the style specifications and then when you instantiate a cell in cellForRowAtIndexPath you can use your custom cell class. So, something like this:
myCell = tableView.dequeueReusableCellWithIdentifier("topicCell") as! topicTableViewCell
Where topicTableViewCell is your own UITableViewCell class