Vincenzo
Vincenzo

Reputation: 6358

manually triggering didSelectRowAtIndexPath in cellForRowAt results in a nil cell in actual didSelectRowAtIndexPath delegate method

I'm trying to manually call the didSelectRowAtIndexPathin cell creation cellForRowAt, because that will update the detail view without having to physically touch the row, but when I do so I get a nil error on cell definition inside the actual delegate method didSelectRowAtIndexPath, while if I don call it inside cellForRowAt it works as expected. I'm assuming that at cell creation time there is actually no cells to read hence the nil value. How can than perform the logic inside didSelectRowAtIndexPath at cell creation time? I thought of opening curly brackets and put the logic there would work but it doesn't accept brackets there.

Can you see if I'm implementing the call to didSelectRowAtIndexPath correctly? Many thanks as always. This are the functions:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "bookingCell", for: indexPath) as! BookingTableViewCell
        let booking = self.fetchedResultController?.object(at: indexPath)
        // Configure the cell...

        cell.cellId = booking!.bookingId

        cell.bookingId = booking!.bookingId
        print(booking!.bookingId)
        cell.bookingIdInfoLabel.text = booking!.bookingId

        cell.bookingDate = booking!.bookingDate
        cell.bookingDateInfoLabel.text = booking?.bookingDate

        cell.bookingStart = booking!.bookingStart
        cell.bookingStartInfoLabel.text = booking?.bookingStart

        cell.bookingEnd = booking!.bookingEnd
        cell.bookingEndInfoLabel.text = booking?.bookingEnd

        cell.bookingPrice = booking!.bookingPrice
        cell.worksDescription = booking!.worksList

        cell.customerName = booking!.customerName
        cell.customerNameInfoLabel.text = booking?.customerName

        cell.cellView.layer.cornerRadius = cornerRadius
        cell.cellView.clipsToBounds = true

        cell.bookingIdInfoLabel.layer.cornerRadius = cornerRadius
        cell.bookingIdInfoLabel.clipsToBounds = true

        cell.bookingDateInfoLabel.layer.cornerRadius = cornerRadius
        cell.bookingDateInfoLabel.clipsToBounds = true

        cell.bookingStartInfoLabel.layer.cornerRadius = cornerRadius
        cell.bookingStartInfoLabel.clipsToBounds = true

        cell.bookingEndInfoLabel.layer.cornerRadius = cornerRadius
        cell.bookingEndInfoLabel.clipsToBounds = true

        cell.customerNameInfoLabel.layer.cornerRadius = cornerRadius
        cell.customerNameInfoLabel.clipsToBounds = true

        // set the corresponding row for the selected time slot's booking as selected
        if cell.cellId == self.bookingId {
            tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.middle) // select timeslot's corresponding row
            self.tableView(self.bookingTableView, didSelectRowAt: indexPath)

        }
        return cell
    }


    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.cellForRow(at: indexPath) as! BookingTableViewCell

        print("selected cell id is : \(cell.cellId!)")
        self.bookingIdInfoLabel.text = cell.bookingId
        self.bookingDateInfoLabel.text = cell.bookingDate
        self.bookingStartInfoLabel.text = cell.bookingStart
        self.bookingEndInfoLabel.text = cell.bookingEnd
        self.priceInfoLabel.text = cell.bookingPrice
        self.customerInfoLabel.text = cell.customerName
        self.worksDescriptionInfoTextVIew.text = cell.worksDescription

    }

Upvotes: 0

Views: 458

Answers (2)

RajeshKumar R
RajeshKumar R

Reputation: 15758

Create a new function where you change text of labels depending the booking selection

func updateSelection(_ selectedBooking: Booking) {
    print("selected cell id is : \(booking.bookingId!)")
    self.bookingIdInfoLabel.text = booking.bookingId
    self.bookingDateInfoLabel.text = booking.bookingDate
    self.bookingStartInfoLabel.text = booking.bookingStart
    self.bookingEndInfoLabel.text = booking.bookingEnd
    self.priceInfoLabel.text = booking.bookingPrice
    self.customerInfoLabel.text = booking.customerName
    self.worksDescriptionInfoTextVIew.text = booking.worksList
}

In didSelectRowAt call this method like this

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.updateSelection(self.fetchedResultController?.object(at: indexPath))
}

call the same method in cellForRowAt

if booking!.bookingId == self.bookingId {
    self.updateSelection(self.fetchedResultController?.object(at: indexPath))
}
    return cell
}

Upvotes: 2

AjinkyaSharma
AjinkyaSharma

Reputation: 1979

Here is what I would suggest

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "bookingCell", for: indexPath) as! BookingTableViewCell
    let booking = self.fetchedResultController?.object(at: indexPath)
    cell.config(booking:booking)
    if booking.bookingId == self.bookingId {
        self.performChanges(forBooking:booking)
    }
}


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath) as! BookingTableViewCell
    let booking = cell.booking
    self.performChanges(forBooking:booking)
}

func performChanges(booking:Booking) {
    //perform all the changes that you did in didSelectRow before
}

//Inside cell
var booking:Booking?
func config(booking:Booking) {
    self.booking = booking
    //set all the data and manipulate the ui here
}

Did not test this code, but hope you get the gist. If you need more info or not able to understand what exactly is to be done, drop a comment and I can elaborate more.

Upvotes: 0

Related Questions