2017-12-28 10 views
1

Ich mache Einheit Konverter App mit benutzerdefinierten Zellen, jede Zelle hat ein Textfeld innen und die Idee war, wenn Sie den Wert in einer Einheit eingeben alle Einheiten automatisch berechnet werden, die Problem ist nur, wenn es mehr Zellen gibt und wenn Sie scrollen müssen, wenn Zellen wiederverwendet werden, verwirren sie Tags und weil meine Funktion für die Berechnung über die Tag-Zelleneigenschaft funktioniert, bekomme ich falsche Werte. Hier ist mein Code und ich werde auch einen Screenshot meines Projekts im Voraus danken. Nicht: Ich weiß, dass einige Teile dynamischer und besser geschrieben sein könnten, aber ich bin neu in der iOS-Welt, also wusste ich in dieser Zeit nicht wirklich, wie ich es besser machen könnte.Swift UITableViewCell Wiederverwendung ist verwirrend Tags/App hat falsche Berechnung

Wenn Sie irgendwelche Fragen über den Code haben, werde ich gerne antworten. enter image description here Screenshot

import UIKit 

    protocol Initializable { 
     init() 
    } 

    class ValuesTableViewController: UITableViewController, Initializable, UITextFieldDelegate { 

     @IBOutlet var valuesTableView: UITableView! 
     var valueName: String? 
     var valueColor: UIColor? 
     var selectedValueObject: Properties? 
     var listOfAllUnitObjects = [AnyObject]() 
     var doubleTextValue : Double? 
     var listOfAllCells = [ValuesCell]() 
     var listOfCurrentValues = [Double]() 
     var returningCalculatedValue : Double? 
     var changingObject: Properties? 
     var selected = [Int : String]() 
     var selectedTag : Int? 
     var noValues: String? 
     var colorChange: UIColor? 
     var classValues: [Properties.Type] = [Properties.Type]() 
     var selectedTextField: Int? 
     var activeField: UITextField? 
     var imageName: String? 
     let listOfAllIndexes: [Int] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] 
     // var testTextField : UITextField 
     //"m²","km²","ha","dm²","cm²","mm²","sq mi", "ac", "sq yd","sq ft", "sq in" 
     // var areaValues: [String: Area] = ["m²": Acre(), "km²": SquareKilometer(), "ha": Hectare(), "dm²": SquareDecimeter(), ""] 
     //var listOfAllUnitsInClass = [Acre,Hectare,SquareCentimeter,SquareDecimeter,SquareFoot,SquareInch,] 





     override func viewDidLoad() { 
      super.viewDidLoad() 



     } 

    // override func numberOfSections(in tableView: UITableView) -> Int { 
    //  // #warning Incomplete implementation, return the number of sections 
    //  return 0 
    // } 

     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
      // #warning Incomplete implementation, return the number of rows 
      let valuesType = configureTable() 
      let valuesObject = createInstance(typeThing: valuesType) 
      // print("Value of listOfMainLabels in numberOfRowsInSection : \(valuesObject.listOfMainLabels.count)") 

      return valuesObject.listOfMainLabels.count 

     } 

     func textFieldDidBeginEditing(_ textField: UITextField) { 
      activeField = textField 
      selectedTextField = textField.tag 

      for i in (0...listOfAllCells.count - 1){ 
       if let textFieldTag = selectedTextField { 
        listOfAllCells[textFieldTag].cellView.backgroundColor = UIColor.white 
        if let imgName = imageName { 
         listOfAllCells[textFieldTag].cellImg.image = UIImage(named: imgName) 
        } 
        if i == textFieldTag { 

        }else{ 
        listOfAllCells[i].cellView.backgroundColor = UIColor(red: 232/255.0, green: 232/255.0, blue: 232/255.0, alpha: 1.0) 
        listOfAllCells[textFieldTag].cellImg.image = nil 
        } 

      } 
      } 
      textField.text = "" 
      textField.keyboardType = UIKeyboardType.decimalPad 
      let valuesType = configureTable() 
      let valuesObject = createInstance(typeThing: valuesType) 
      if textField.text == "" { 
       //Ovde nastaje problem jer samo vrati unetu vrednost 
       let entryValueReturned = checkTypesForSelected(tag: textField.tag, cells: listOfAllCells, entryValues: 0, valuesObject: valuesObject) 
       returningCalculatedValue = entryValueReturned 
       if let returnCalculatedValue = returningCalculatedValue { 
        checkTypes(tag: textField.tag, allCells: listOfAllCells, entryValues: returnCalculatedValue, valuesObject: valuesObject) 
        selectedTag = textField.tag 
        selected[textField.tag] = "0" 
        // print("Prolazi druga funkcija") 
        //valuesTableView.reloadData() 
       } 

      } 
     } 
     func textFieldDidEndEditing(_ textField: UITextField) { 
      //Deleting previous entered value and setting to blank 

      activeField = nil 
      if textField.text == "" { 

       noValues = "" 

      } 




     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
      let valuesType = configureTable() 
      let valuesObject = createInstance(typeThing: valuesType) 

      //Creating an instance of the object that the user previously selected getting the listOfMainValues which are unit labels 

      //print("TableView called \(indexPath.row)") 

      let cell = tableView.dequeueReusableCell(withIdentifier: "valueCell", for: indexPath) as! ValuesCell 
      print("Tag for this cell would have been \(indexPath.row)") 
      if indexPath.row == 0 { 
       cell.cellView.backgroundColor = UIColor.white 
       if valuesObject is Area { 
        //Depending of what unit category is selected different image is used 
        imageName = "area-arrow" 
        cell.cellImg.image = UIImage(named: imageName!) 
       }else if valuesObject is Temperature{ 
        imageName = "temperature-arrow" 
        cell.cellImg.image = UIImage(named: imageName!) 
       }else if valuesObject is Length { 
        imageName = "length-arrow" 
        cell.cellImg.image = UIImage(named: imageName!) 
       }else if valuesObject is Mass { 
        imageName = "mass-arrow" 
        cell.cellImg.image = UIImage(named: imageName!) 
       }else if valuesObject is Speed { 
        imageName = "speed-arrow" 
        cell.cellImg.image = UIImage(named: imageName!) 
       }else if valuesObject is Volume { 
        imageName = "volume-arrow" 
        cell.cellImg.image = UIImage(named: imageName!) 
       }else if valuesObject is FuelConsumption { 
        imageName = "fuel-arrow" 
        cell.cellImg.image = UIImage(named: imageName!) 
       }else if valuesObject is Time { 
        imageName = "time-arrow" 
        cell.cellImg.image = UIImage(named: imageName!) 
       }else if valuesObject is DigitalStorageData { 
        //Same for all other units ... 
       } 
      } 

      let currentClassName = valuesObject.listOfAllUnits[indexPath.row] 
      let unitObject = stringClassFromString(currentClassName) 

      cell.cellTextBox.delegate = self 
      cell.cellTextBox.addTarget(self, action: #selector(self.textFieldDidChange(_:)), for: .editingChanged) 
      //button.addTarget(self, action: #selector(self.buttonClicked(sender:)), for: .touchUpInside) 
      //Setting values from an array to cell label 
      cell.cellMainLbl.text = valuesObject.listOfMainLabels[indexPath.row] 
      cell.cellSmallLbl.text = valuesObject.listofSmallLabels[indexPath.row] 
    //   cell.valueLabel.textColor = UIColor.init(red: CGFloat(rColorValue[indexPath.row]), green: CGFloat(gColorValue[indexPath.row]), blue: CGFloat(bColorValue[indexPath.row]), alpha: 1.0) 
    //   cell.leftColorView.backgroundColor = UIColor.init(red: CGFloat(rColorValue[indexPath.row]), green: CGFloat(gColorValue[indexPath.row]), blue: CGFloat(bColorValue[indexPath.row]), alpha: 1.0) 
      cell.tag = listOfAllIndexes[indexPath.row] 
      cell.cellTextBox.tag = listOfAllIndexes[indexPath.row] 
      print("Cell tag : \(cell.tag) and CellTextBox tag: \(cell.cellTextBox.tag)") 
      cell.cellTextBox.borderStyle = .none 
      if valuesObject.listOfMainLabels.count - 1 >= listOfAllCells.count { 
       listOfAllCells.append(cell) 
      } 
      //listOfAllUnitObjects.append(unitObject) 
      if let unitObjectUnwrapped = unitObject { 
       listOfAllUnitObjects.append(unitObjectUnwrapped) 
      } 

    //  for unit in valuesObject.listOfAllUnits { 
    //   let unitObject = stringClassFromString(unit) 
    //   if let unitObjectUnwrapped = unitObject { 
    //    listOfAllUnitObjects.append(unitObjectUnwrapped) 
    //   } 
    // 
    // 
    //  } 

    //  //cell.imageView?.image = UIImage(named: fruitName) 
    //  cell.rightValueImage.image = UIImage(named: "\(indexPath.row)") 
      if selected[indexPath.row] != nil { 
       cell.cellTextBox.text = selected[indexPath.row] 
       //print("Ako ovo prodje znaci sredjuj sledecu funkciju koja ih namesta na default da ignorise ovu celiju") 
      } 
      // Configure the cell... 
      return cell 
     } 
     override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 
      //Save the last selected textfield value 
      let valuesType = configureTable() 
      let valuesObject = createInstance(typeThing: valuesType) 

      if let seleTag = selectedTag { 
       let valueString = selected[seleTag] 
       if let valueS = valueString { 
        if let value = Double(valueS){ 
         if value == 0 { 
          print("Da vidimo da li upada ovde : \(selected[selectedTag!]!)") 
          let valueFromMethod = checkTypesForSelected(tag: seleTag, cells: listOfAllCells, entryValues: 0, valuesObject: valuesObject) 
          checkTypes(allCells: listOfAllCells, entryValues: valueFromMethod, valuesObject: valuesObject) 
          print("PROLAZI ZA 0 checkTypes") 
         }else{ 
          da li je uopste value nekada 0 ili je uvek razlicit od nule 
          print("value vrednost: \(value)") 
          let methodValue = checkTypesForSelected(tag: seleTag, cells: listOfAllCells, entryValues: value, valuesObject: valuesObject) 
          checkTypes(tag: seleTag, allCells: listOfAllCells, entryValues: methodValue, valuesObject: valuesObject) 
          print("OBRATI PAZNU!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") 
         } 

        } 

        } 

       //Problem: kada ne unese vrednost vraca ih na 1 umesto na 0 
       //Ovde radim trenutno 
      }else{ 
       checkTypes(allCells: listOfAllCells, entryValues: 1, valuesObject: valuesObject) 
       print("ZAVRSILA SE METODA SA POZIVOM 1") 


      } 

      if let changeColor = colorChange { 
       if indexPath.row == 0 { 
        let cell = tableView.dequeueReusableCell(withIdentifier: "valueCell", for: indexPath) as! ValuesCell 
        cell.cellView.backgroundColor = changeColor 
       } 
      } 
      //checkTypes(allCells: listOfAllCells,entryValues: 1, valuesObject: valuesObject) 
      //print("Value of listOfAllCells in willDisplay : \(listOfAllCells.count)") 
      valuesTableView.tableFooterView = UIView() 
      valuesTableView.tableFooterView?.backgroundColor = UIColor.gray 
    //  valuesTableView.tableFooterView?.backgroundColor = UIColor(red: 232/255.0, green: 232/255.0, blue: 232/255.0, alpha: 1.0) 
     } 
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 


      let cell = tableView.cellForRow(at: indexPath) as! ValuesCell 
      if (cell.cellTextBox.text?.isEmpty)!{ 
       cell.cellTextBox.text = "0.0" 
      } 
      print("Cell clicked has a tag \(cell.tag)") 



       for i in (0...listOfAllCells.count - 1){ 
        if i == indexPath.row { 
         cell.cellView.backgroundColor = UIColor.white 
         if let imageTxt = imageName { 
          cell.cellImg.image = UIImage(named: imageTxt) 
          print("Prosla slika") 
         } 
        }else{ 
         colorChange = cell.backgroundColor 
         listOfAllCells[i].cellView.backgroundColor = UIColor(red: 232/255.0, green: 232/255.0, blue: 232/255.0, alpha: 1.0) 
         cell.cellImg.image = nil 
        } 

       } 
    // 

      self.view.endEditing(true) 


     } 
     override func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle { 
      return .none 
     } 

     override func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool { 
      return false 
     } 


     func checkTypes<T>(allCells: [ValuesCell],entryValues: Double, valuesObject: T){ 

      if valuesObject is Area { 

      //When cells appear for the first time calculate for 1 all units 
      classValues = [SquareMeter.self, SquareKilometer.self, Hectare.self, SquareDecimeter.self, 
              SquareCentimeter.self, SquareMillimeter.self, SquareMile.self, Acre.self, 
              SquareYard.self, SquareFoot.self, SquareInch.self] 
    //   print("classValues count je : \(classValues.count)") 
    //   print("listOfAllCells count je: \(listOfAllCells.count)") 


       //Napravi da ako i bude jednako tagu da preskoci tu vrednost jer zelimo da ostane to sto je korisnik uneo 
       //u tom polju 
       for i in 0...(listOfAllCells.count - 1){ 
         //print("Ovde baca index out of range i ima vrednost: \(i)") 
         let object = classValues[i].init() 
         let value = object.ConvertFromMainUnitToUnit(entryValue: entryValues) 
         //print("Vracam vrednost druge metode za \(i) element je : \(value)") 
         listOfAllCells[i].cellTextBox.text = "\(value)" 



        } 
      }else if valuesObject is Temperature { 
       classValues = [Celsius.self, Fahrenheit.self, Kelvin.self] 
       for i in 0...(listOfAllCells.count - 1){ 
        let object = classValues[i].init() 
        let value = object.ConvertFromMainUnitToUnit(entryValue: entryValues) 
        element je : \(value)") 
        listOfAllCells[i].cellTextBox.text = "\(value)" 


       } 
      }else if valuesObject is Length { 
       classValues = [Meter.self, CentiMeter.self, DeciMeter.self, Foot.self, Inch.self, 
                KiloMeter.self, MicroMeter.self, Mile.self, MillieMeter.self, NanoMeter.self, NauticMile.self,Yard.self] 
       for i in 0...(listOfAllCells.count - 1){ 
        let object = classValues[i].init() 
        let value = object.ConvertFromMainUnitToUnit(entryValue: entryValues) 
        element je : \(value)") 
        listOfAllCells[i].cellTextBox.text = "\(value)" 


       } 
      }else if valuesObject is Mass { 
       classValues = [KiloGram.self, DecaGram.self, Gram.self,LongTon.self, MetricTon.self, 
               MicroGram.self, MilliGram.self, Ounce.self, Pound.self, ShortTon.self, Stone.self] 
       for i in 0...(listOfAllCells.count - 1){ 
        let object = classValues[i].init() 
        let value = object.ConvertFromMainUnitToUnit(entryValue: entryValues) 
        element je : \(value)") 
        listOfAllCells[i].cellTextBox.text = "\(value)" 


       } 
      }else if valuesObject is Speed { 
       classValues = [MetersPerSecond.self, FeetPerSecond.self, KilometersPerHour.self,Knot.self, MilesPerHour.self] 
       for i in 0...(listOfAllCells.count - 1){ 
        let object = classValues[i].init() 
        let value = object.ConvertFromMainUnitToUnit(entryValue: entryValues) 
        //print("Vracam vrednost druge metode za \(i) element je : \(value)") 
        listOfAllCells[i].cellTextBox.text = "\(value)" 


       } 
      }else if valuesObject is Volume { 
       classValues = [Liter.self, CubicFoot.self, CubicInch.self,CubicMeter.self, 
                ImperialGal.self, ImperialOz.self, ImperialPint.self, ImperialQuart.self, 
                ImperialTableSpoon.self,ImperialTeaSpoon.self, MilliLiter.self, UsCup.self, 
                UsGal.self,UsOz.self,UsPint.self,UsQuart.self,UsTableSpoon.self,UsTeaSpoon.self] 
       for i in 0...(listOfAllCells.count - 1){ 
        let object = classValues[i].init() 
        let value = object.ConvertFromMainUnitToUnit(entryValue: entryValues) 
        //print("Vracam vrednost druge metode za \(i) element je : \(value)") 
        listOfAllCells[i].cellTextBox.text = "\(value)" 


       } 
      }else if valuesObject is FuelConsumption { 


      ...//And for all other Units same thing.. 

      } 

     } 
     func checkTypes<T>(tag: Int, allCells: [ValuesCell],entryValues: Double, valuesObject: T){ 

      if valuesObject is Area { 

       classValues = [SquareMeter.self, SquareKilometer.self, Hectare.self, SquareDecimeter.self, 
           SquareCentimeter.self, SquareMillimeter.self, SquareMile.self, Acre.self, 
           SquareYard.self, SquareFoot.self, SquareInch.self] 

    //   let classValues: [Area.Type] = [SquareMeter.self, SquareKilometer.self, Hectare.self, SquareDecimeter.self, 
    //           SquareCentimeter.self, SquareMillimeter.self, SquareMile.self, Acre.self, 
    //           SquareYard.self, SquareFoot.self, SquareInch.self] 
    //   print("classValues count je : \(classValues.count)") 
    //   print("listOfAllCells count je: \(listOfAllCells.count)") 


       //Fixing index difference between tags going out of bounds 

       for i in 0...(listOfAllCells.count - 1){ 
        if i == tag { 
         print("Evo ga tag \(tag)") 
        }else{ 
         //print("Ovde baca index out of range i ima vrednost: \(i)") 
         let object = classValues[i].init() 
         let value = object.ConvertFromMainUnitToUnit(entryValue: entryValues) 
         //print("Vracam vrednost druge metode za \(i) element je : \(value)") 
         listOfAllCells[i].cellTextBox.text = "\(value)" 

        } 


       } 
      }else if valuesObject is Temperature { 


       ...//And for all other Units same thing.. 



       } 
      } 
     } 
     func checkTypesForSelected<T>(tag: Int,cells: [ValuesCell],entryValues: Double, valuesObject: T) -> Double{ 
//Checking what unit is selected and calculating all values for all units in that category 
      if valuesObject is Area { 

       classValues = [SquareMeter.self, SquareKilometer.self, Hectare.self, SquareDecimeter.self, 
               SquareCentimeter.self, SquareMillimeter.self, SquareMile.self, Acre.self, 
               SquareYard.self, SquareFoot.self, SquareInch.self] 

       if listOfAllUnitObjects[tag] is SquareMeter.Type { 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareMeter.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       } else if listOfAllUnitObjects[tag] is SquareKilometer.Type { 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareKilometer.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is Hectare.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? Hectare.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is SquareDecimeter.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareDecimeter.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is SquareCentimeter.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareCentimeter.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is SquareMillimeter.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareMillimeter.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is SquareCentimeter.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareCentimeter.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is SquareMile.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareMile.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is Acre.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? Acre.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is SquareYard.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareYard.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is SquareFoot.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareFoot.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       }else if listOfAllUnitObjects[tag] is SquareInch.Type{ 
        var testObject = classValues[tag].init() 
        testObject = createInstance(typeThing: (listOfAllUnitObjects[tag] as? SquareInch.Type)!) 
        let value = testObject.ConvertFromUnitToMainUnit(entryValue: entryValues) 
        return value 
       } 

      }else if valuesObject is Temperature { 

       ...//And for all other Units same thing as above.. 
       } 
      } 
      return 0 
     } 
+0

Sie Ihren Code in einem anderen lang als eng kommentierte, es pls korrigieren. –

+0

Ich korrigiere es so schnell wie möglich –

+0

Es ist nicht der richtige Weg, wenn Sie wiederverwendbare Zellen speichern, denn während sie gespeichert sind, können sie wiederverwendet werden und somit einem anderen Gegenstand zugewiesen werden. Versuchen Sie, Ihren Code nur mit Zeilenindexen neu zu schreiben und die Zelle am angegebenen Index neu zu laden, anstatt die Zelle direkt zu ändern. – Varrry

Antwort

0

wie das Versuchen in cellForRow

let cell = tableView.dequeueReusableCell(withIdentifier: "valueCell") as! ValuesCell 
+0

Leider hat dies das Problem nicht behoben danke für den Versuch –

+0

versuchen Sie es erneut wie let cell = ValuesCell() –

Verwandte Themen