我正在制作带有自定义单元格的单位转换器应用程序,每个单元格里面都有一个文本框,想法是当你在一个单元中输入值时,所有单位都会自动计算,问题是只有当有更多单元格时才需要当单元格被重用时滚动它们会弄乱标签,因为我的计算功能通过标签单元属性工作,我得到了错误的值。 这是我的代码,我还将提前提供我的项目的截图。不是:我知道有些部分可以更有活力,更好写,但我是iOS世界的新手,所以在那段时间我真的不知道怎么做得更好。
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 :(得分:0)
在cellForRow
中尝试这样 let cell = tableView.dequeueReusableCell(withIdentifier: "valueCell") as! ValuesCell