2016-09-29 7 views
1

Arbeiten an einem Projekt, bei dem eine Storyboard-Ansicht zwei Klassen benötigt, eine normale UIViewController-Klasse und eine IAxisValueFormatter-Klasse, die mit der zu beschreibenden iOS-Diagrammbibliothek arbeitet eine Achse mit String-Werten. Diese Klassen in relevanten Teilen und in ihrer ursprünglichen (vor Fehlerbehebung) Form dargestellt:Variable kann nicht in eine bestimmte Klasse übergeben werden, Instanzelement kann nicht bei Typfehler verwendet werden

import Foundation 
import Charts 

@objc(BarChartFormatter) 
public class BarChartFormatter: NSObject, IAxisValueFormatter{ 

    var dates: [String]! 

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String { 
     return dates[Int(value)] 
    } 
} 

class SessionRevew: UIViewController { 

    @IBOutlet weak var HBCController: HorizontalBarChartView! 
    var dates: [String]! 

Das Problem ist, dass ich nicht in der Lage gewesen, alle Werte in die IAxisValueFormatter Klasse zu übergeben. Das Übergeben von Werten vom vorherigen Ansichtscontroller an die SessionReview-Klasse ist problemlos und funktioniert weiter.

den folgenden Code aus einer anderen Ansicht Regler durchläuft erfolgreich die Daten-Feld zu dem UIViewController Klasse SessionRevew:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if (segue.identifier == "ReviewData") { 
     let datespass = segue.destination as! SessionRevew 
     datespass.dates = dates 
    } 
} 

Sobald jedoch Code die gleiche Variable zu der anderen Klasse übergeben wird hinzugefügt:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if (segue.identifier == "ReviewData") { 
     let datespass1 = segue.destination as! BarChartFormatter 
     let datespass = segue.destination as! SessionRevew 
     datespass1.dates = dates 
     datespass.dates = dates 
    } 
} 

der Code in betriebsfähigen wird, wie die Aktivierung des segue diese Fehler auslöst: EXC_BAD_INSTRUCTION error

Was an der Linie passiert: lass datespass1 = segue.destination als! BarChartFormatter Wenn jemand mir helfen kann zu verstehen, warum dies fehlschlägt und wie man das Array an diese Klasse weitergibt, ist dies die ideale Antwort. Das Folgende stellt einige Bemühungen dar, diesen Fehler zu umgehen, indem Sie die Variable aus der SessionReview-Klasse für die andere Klasse freigeben. Wir haben zunächst eine sekundäre Variable in der anderen Klasse, die in dieser Folge:

@objc(BarChartFormatter) 
public class BarChartFormatter: NSObject, IAxisValueFormatter{ 

    var BCFdates = SessionRevew.dates 

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String { 
     return BCFdates[Int(value)] 
    } 
} 

Dieser Code wird nicht kompiliert aufgrund des Fehlers „Instanz Mitglieds Daten 'nicht auf Typen SessionRevew verwendet werden kann“, das auf das auftritt line:

var BCFdates = SessionRevew.dates 

Wir versuchen, die obige Klasse innerhalb der Klasse SessionRevew Verschachtelung, die exakt die gleichen Fehler ergab. Bei dem Versuch, diesen Fehler zu beheben, fanden wir die Lösung hier gezeigt: https://stackoverflow.com/a/32693285/6889264 und versuchen, es zu implementieren, wie so:

import Foundation 
import Charts 

class SessionRevew: UIViewController { 

    @IBOutlet weak var HBCController: HorizontalBarChartView! 

    var dates: [String]! 

    @objc(BarChartFormatter) 
    public class BarChartFormatter: NSObject, IAxisValueFormatter{ 

     var BCFdates: [String] { 
      get { 
       return { 
        SessionRevew.dates 
        } 
       } 
     } 

     public func stringForValue(_ value: Double, axis: AxisBase?) -> String { 
      return BCFdates[Int(value)] 
     } 
    } 
} 

Leider ist der Fehler bleibt genau das gleiche ("Instance Mitglied‚Daten‘nicht verwendet werden kann auf type SessionRevew ") und der Code kompiliert nicht. Un-Verschachtelung der Klasse gibt:

import Foundation 
import Charts 

@objc(BarChartFormatter) 
public class BarChartFormatter: NSObject, IAxisValueFormatter{ 

    var BCFdates: [String] { 
     get { 
      return { 
       SessionRevew.dates 
      } 
     } 
    } 

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String { 
     return BCFdates[Int(value)] 
    } 
} 

class SessionRevew: UIViewController { 

    @IBOutlet weak var HBCController: HorizontalBarChartView! 
    var dates: [String]! 
} 

Dieser Code erzeugt auch den Fehlercode: „Instanz Mitglieds Daten 'kann auf Typ SessionRevew nicht verwendet werden“. Dann versuchte die BCFdates Variable als nur lesen berechnet Eigenschaft in Übereinstimmung mit dieser Lösung zu einem ähnlichen Problem zu definieren: https://stackoverflow.com/a/38651304/6889264

var BCFdates: [String] { 
    return SessionRevew{dates} 
} 

Aber der Compiler-Fehler blieb. Irgendwelche Lösungen oder Erklärungen, die diesen Code zum Funktionieren bringen, würden sehr geschätzt werden. Wie bereits erwähnt, wäre es ideal, wenn wir das Array direkt an die BarChartFormatter-Klasse übergeben und die Freigabe zwischen Klassenproblemen vergessen würden.

EDIT

Die BarChartFormatter in der SessionRevew Klasse durch die Funktion setChart in der folgenden Art und Weise verwendet werden:

func setChart(_ dataPoints: [String], values: [Double]) { 
    let formato:BarChartFormatter = BarChartFormatter() 

for i in 0..<dataPoints.count { 
     let dataEntry = BarChartDataEntry(x: Double(i), yValues: [values[i]]) 
     dataEntries.append(dataEntry) 
     formato.stringForValue(Double(i), axis: xaxis) 
    } 
    xaxis.valueFormatter = formato 
    HBCController.xAxis.valueFormatter = xaxis.valueFormatter 
} 

Es ist nirgendwo sonst im Code verwiesen wird.

+1

Nach dem Lesen der ersten Hälfte Ihrer Frage habe ich ein paar Fragen. Wie können Sie davon ausgehen, dass ein 'BarChartFormatter' ein 'segue.destination' ist, wenn es kein View-Controller ist? Zweitens, auch wenn das funktioniert, erwartet Ihr Code, dass die "segue.destination" ein völlig anderer Objekttyp ist, wenn er in die nächste Zeile gelangt. Wie denkst du, dass das funktionieren kann? –

+0

Wie kann man Variablen an den BarChartFormatter übergeben? Gibt es eine andere Methode, die ich hätte verwenden sollen? –

+1

** Pragmatischer, was erstellt/besitzt eine Instanz von 'BarChartFormatter'? ** –

Antwort

0

Wie von Phillip vorgeschlagen, besteht die Lösung darin, auf den Versuch zu verzichten, die Variable während des Übergangs an den BarChartFormatter zu übergeben, und stattdessen die Variable in der setChart-Funktion weiterzuleiten.

nur eine neue Zeile Code erforderlich:

formato.dates = self.dates 

Dies ist auf die setChart Funktion nach der Zeile sofort hinzugefügt wird:

let formato:BarChartFormatter = BarChartFormatter() 

Der ursprüngliche BarChartFormatter Code (siehe unten), dann funktioniert perfekt mit dem Datumsfeld.

@objc(BarChartFormatter) 
public class BarChartFormatter: NSObject, IAxisValueFormatter{ 

    var dates: [String]! 

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String { 
     return dates[Int(value)] 
    } 
} 

auch als Phillip angedeutet, ist es unmöglich, die Termine Array auf die BarChartFormatter Klasse mit dem segue.destination Code zu übergeben, so dass nicht versucht werden muss. Also diese Version dieses Codes ist die richtige:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
    if (segue.identifier == "ReviewData") { 
     let datespass = segue.destination as! SessionRevew 
     datespass.dates = dates 
    } 
} 
Verwandte Themen