2017-05-12 7 views
0

Lassen Ich habe eine UITableView mit 2 Prototyp-Zellen: CourseCell und BllCell. Diese Zellen enthalten einen UISlider und eine IBAction befindet sich auf dem Haupt-ViewController.Swift: Wenn mit mehreren Zellen Klassen

Nachdem der Schieber abgeschlossen hat, wird die folgende Aktion zu bewegen ausgelöst:

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

Wie Sie sehen können, gibt doppelten Code ist. Ist es möglich zu feuern, wenn Zelle ... sowohl mit CourseCell als auch mit BlllCell verbunden ist, um auf die Variable cell.activeSemester in beiden zuzugreifen, ohne die Funktion duplizieren zu müssen?

+3

Neben dem Spaghetti-Code Sie mit uns geteilt haben, das ist wirklich die schrecklichste Art und Weise Zelle von ihrer subsub Ansicht zu bekommen. Sie sollten Ihre Logik neu gestalten und die Verwendung von [Delegaten] in Erwägung ziehen (https://developer.apple.com/library/content/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html). – ozgur

+3

Warum bekommen Sie die Zelle? Greifen Sie auf Ihr Datenmodell zu, nicht auf die Ansicht. – rmaddy

+1

... und mit Ausnahme der beiden "default" -Brüche können Sie alle anderen 'break'-Anweisungen auslassen. Sie werden nicht in Swift benötigt. – vadian

Antwort

3

Sie müssen einen gemeinsamen Elternteil für beide BllCellCourseCell machen, wenn Sie die gleiche Anweisung ausführen.

+2

Das kann oder kann nicht nützlich sein. Die wirkliche Antwort ist, den Zugriff auf die Zelle überhaupt im Code zu vermeiden. Es gibt keinen Grund, warum der Code in der Frage überhaupt versuchen sollte, auf eine Zelle zuzugreifen. – rmaddy

+0

Ich hoffe du verstehst das :) –

0

Es gibt zahlreiche Probleme mit diesem Code aber die unmittelbare Antwort auf Ihre Frage ist ein Protokoll zu verwenden:

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

Beide CourseCell und BllCell sollen dieses Protokoll entsprechen.

dass der duplizierten Code halbiert:

@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() 
    } 
} 
Verwandte Themen