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

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

Related

Missing return in a function expected to return 'UITableViewCell' ; please help me

extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.deselectRow(at: indexPath, animated: true)
let vc = storyboard?.instantiateViewController(identifier: "tasks") as! TaskViewController
vc.title = "New Tasks"
vc.task = tasks[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
//error:Missing return in a function expected to return 'UITableViewCell'
}
}
I try diffrence of return type but none of them are correct
The process is wrong in this function you are supposed to create a cell instance and work with it to be able to return it
Code modified:
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
/// Create a file for the cell let's say call it `myCell` with a label for task "let's suppose called `lblTaskOutlet`
let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! myCell
myCell.lblTaskOutlet = tasks[indexPath.row]
return cell
}
}
You can add this vc.title = "New Tasks" in your viewDidLoad() :
self.title = "New Tasks"
The below line is another function called alone with its own body:
tableView.deselectRow(at: indexPath, animated: true)
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell method is a tableview delegate method which populates the cells for each row. It is expecting a return type of UITableViewCell.
You can create UITableViewCell subclass TaskCell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
/// Create a file for the cell let's say call it `TaskCell` with a object for task "let's suppose called `taskObj`
let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! TaskCell
cell.taskObj = tasks[indexPath.row]
return cell
}
For the click action on cell you have to override another UITableViewDataSource method.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = storyboard?.instantiateViewController(identifier: "tasks") as! TaskViewController
vc.title = "New Tasks"
vc.task = tasks[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
}
And please make sure that you have set tableview delegate and datasource in view did load of your view controller.
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
}

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

How to maintain highlighted multiple UITableView rows after reloading UITableView?

I have a UITableView.
I can select multiple cells make them highlighted.
But, whenever I reload App, the selected and highlighted state disappears.
I think I need to put some codes in 'viewDidAppear' and 'didSelectRowAt'. But I don't have any idea of specific codes.
What do I have to put in this syntax?
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tableView.reloadData()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
I recommend u add to dataSource item field selected, and in method cellForRowAtindexPath configure by your dataSource items.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cellClass = (self.cellClass(for: indexPath) ?? self.cellClasses.first) else { return UITableViewCell() }
let cell = tableView.dequeueReusableCell(withIdentifier: cellClass.identifier, for: indexPath)
if let configurable = cell as? ConfigurableComponent, let object = self.object(at: indexPath) {
let item = self.dataSource[indexPath.row]
configurable.selected = item.selected
}
return cell
}
When call didSelectRowAt, just take item and change selected field, sample:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = self.dataSource[indexPath.row]
item.selected = !item.selected
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)
}

Create object that conform to protocol in 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
}