Liam94
Liam94

Reputation: 13

Swift: If Let with Multiple Cell Classes

I have a UITableView with 2 prototype cells: CourseCell and BllCell. These cells contain a UISlider and an IBAction is in place on the main ViewController.

After the slider has finished moving the following action is triggered:

@IBAction func sliderFinishedMoving(_ sender: Any) {
    if let slider = sender as? gradeSlider {
        if let superview = slider.superview {

            if let cell = superview.superview as? CourseCell {

                let selectedSemester = cell.activeSemester

                let selectedIndexPath = courseTable.indexPath(for: cell)!
                let selectedCourse = courseTypes[selectedIndexPath.section].courses[selectedIndexPath.row]

                if selectedCourse.examType == "" && selectedCourse.examCourse == true {
                    print("please select the exam type before entering grades")
                    slider.value = 0.0
                    cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)
                    cell.gradeSliderLabel.text = "0"
                    return
                }

                print(selectedIndexPath.section, selectedIndexPath.row)

                slider.value = round(slider.value)
                cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)

                switch(selectedSemester) {
                case 1:
                    selectedCourse.semester1Grade = Int(slider.value)
                    break
                case 2:
                    selectedCourse.semester2Grade = Int(slider.value)
                    break
                case 3:
                    selectedCourse.semester3Grade = Int(slider.value)
                    break
                case 4:
                    selectedCourse.semester4Grade = Int(slider.value)
                    break
                case 5:
                    selectedCourse.examGrade = Int(slider.value)
                    break
                case 6:
                    selectedCourse.oralGrade = Int(slider.value)
                    break
                default:
                    break
                }

                courseTable.reloadData()
            }

            if let cell = superview.superview as? BllCell {

                let selectedSemester = cell.activeSemester

                let selectedIndexPath = courseTable.indexPath(for: cell)!
                let selectedCourse = courseTypes[selectedIndexPath.section].courses[selectedIndexPath.row]

                if selectedCourse.examType == "" && selectedCourse.examCourse == true {
                    print("please select the exam type before entering grades")
                    slider.value = 0.0
                    cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)
                    cell.gradeSliderLabel.text = "0"
                    return
                }

                print(selectedIndexPath.section, selectedIndexPath.row)

                slider.value = round(slider.value)
                cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)

                switch(selectedSemester) {
                case 1:
                    selectedCourse.semester1Grade = Int(slider.value)
                    break
                case 2:
                    selectedCourse.semester2Grade = Int(slider.value)
                    break
                case 3:
                    selectedCourse.semester3Grade = Int(slider.value)
                    break
                case 4:
                    selectedCourse.semester4Grade = Int(slider.value)
                    break
                case 5:
                    selectedCourse.examGrade = Int(slider.value)
                    break
                case 6:
                    selectedCourse.oralGrade = Int(slider.value)
                    break
                default:
                    break
                }

                courseTable.reloadData()
            }
        }
    }
}

As you can see, there is duplicate code. Is it possible to fire if let cell ... with both CourseCell and BllCell in order to access the cell.activeSemester variable in both without having to duplicate the function?

Upvotes: 0

Views: 121

Answers (2)

Daniel T.
Daniel T.

Reputation: 33967

There are numerous issues with this code but the immediate answer to your specific question is to use a protocol:

protocol GradeSliderCell: class {
    var activeSemester: Int { get }
    var gradeSliderLabel: UILabel! { get }
}

Both CourseCell and BllCell should conform to this protocol.

That cuts the duplicated code in half:

@IBAction func sliderFinishedMoving(_ sender: Any) {
    guard let slider = sender as? gradeSlider else { return }
    guard let superview = slider.superview else { return }

    if let cell = superview.superview as? GradeSliderCell {

        let selectedSemester = cell.activeSemester

        let selectedIndexPath = courseTable.indexPath(for: cell as! UITableViewCell)!
        let selectedCourse = courseTypes[selectedIndexPath.section].courses[selectedIndexPath.row]

        if selectedCourse.examType == "" && selectedCourse.examCourse == true {
            print("please select the exam type before entering grades")
            slider.value = 0.0
            cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)
            cell.gradeSliderLabel.text = "0"
            return
        }

        print(selectedIndexPath.section, selectedIndexPath.row)

        slider.value = round(slider.value)
        cell.gradeSliderLabel.frame.origin.x = slider.thumbCenterX - (cell.gradeSliderLabel.frame.width/2)

        switch(selectedSemester) {
        case 1:
            selectedCourse.semester1Grade = Int(slider.value)
        case 2:
            selectedCourse.semester2Grade = Int(slider.value)
        case 3:
            selectedCourse.semester3Grade = Int(slider.value)
        case 4:
            selectedCourse.semester4Grade = Int(slider.value)
        case 5:
            selectedCourse.examGrade = Int(slider.value)
        case 6:
            selectedCourse.oralGrade = Int(slider.value)
        default:
            break
        }

        courseTable.reloadData()
    }
}

Upvotes: 0

Salman Ghumsani
Salman Ghumsani

Reputation: 3657

You have to make a common parent for both BllCell CourseCell if you are performing the same instruction.

Upvotes: 3

Related Questions