2017-01-10 6 views
0

Вот главный экран приложения:Создание ТРИ pickerViews для преобразования единиц

enter image description here

Я успешно связал это pickerView друг к другу, а затем я попытался назначить вычисление в преобразовании, но не

ex: миля to killo , но я не мог найти способ сделать это. Я попытался использовать «Switch», но ничего не случилось. Мне просто нужно, чтобы кто-то мог показать мне, как я могу конвертировать из определенной единицы в другую единицу через textFields. Например, если вы вводите значение в определенном texField, преобразованный результат будет в другом текстовом поле и наоборот.

Вот мой код:

import UIKit 

класс ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate {

@IBOutlet weak var mainPicker: UIPickerView! 
@IBOutlet weak var leftPicker: UIPickerView! 
@IBOutlet weak var rightPicker: UIPickerView! 
@IBOutlet weak var textFieldLeft: UITextField! 
@IBOutlet weak var textFielfRight: UITextField! 
@IBOutlet weak var equal: UILabel! 


var leftPickerData : [String] = [] 
var rightPickerData : [String] = [] 

var dataDict:NSMutableDictionary! 
var mainPickerData:NSArray! 
var leftRightPickerData:NSArray! 

//yourPicker.backgroundColor = UIColor(patternImage: UIImage(named: "back.jpg")!) 


override func viewDidLoad() { 
    super.viewDidLoad() 

    mainPicker.backgroundColor = .clear 
    rightPicker.backgroundColor = .clear 
    leftPicker.backgroundColor = .clear 

    // Connect data to ViewController .. 
    self.mainPicker.delegate = self 
    self.mainPicker.dataSource = self 

    self.leftPicker.delegate = self 
    self.leftPicker.dataSource = self 

    self.rightPicker.delegate = self 
    self.rightPicker.dataSource = self 

    self.textFieldLeft.delegate = self 
    self.textFielfRight.delegate = self 

    let theWidth = view.frame.size.width 
    let theHeight = view.frame.size.height 

    mainPicker.center = CGPoint(x: theWidth/2, y: theHeight/2 - 182.5) 
    leftPicker.center = CGPoint(x: theWidth/2 - 100, y: theHeight/2) 
    rightPicker.center = CGPoint(x: theWidth/2 + 100, y: theHeight/2) 
    textFieldLeft.center = CGPoint(x: theWidth/2 - 90, y: theHeight/2 + 110) 
    textFielfRight.center = CGPoint(x: theWidth/2 + 90, y: theHeight/2 + 110) 
    equal.center = CGPoint(x: theWidth/2, y: theHeight/2 + 110) 



    dataDict = ["Area":["Square Mile", "Square Yard", "Square Foot", "Square Inch", "Hectare", "Acre", "Square Kilometer", "Square Meter", "Square Centimeter", " Square Millimeter"] 
     ,"Energy":["Btus", "Calories", "Ergs", "Foot-Pounds", "Joules", "Kilogram-Calories", "Kilogram-Meters", "Kilowatt-Hours", "Newton-Meters", "Watt-Hours"], "Length":["Mile", "Yard", "Foot", "Inch", "Kilometer", "Meter", "Centimeter", "Millimeter"], "Power": ["Btus/Minute", "Foot-Pounds/Min", "Foot-Pounds/Sec", "Horsepower", "Kilowatts", "Watts"], "Pressure": ["Pounds/Sqr Ft", "Pounds/Sqr In", "Atmospheres", "Bars", "In of Mercury", "Cm of Mercury", "Kilograms/Sqr Meter", "Pascals"], "Speed": ["Knots", "Miles/Hr", "Miles/Min", "Feet/Min", "Feet/Sec", "Kilometers/Hr", "Kilometer/Min", "Meters/Sec"], "Temperature": ["Celsius C˚", "Fahrenheit", "Kelvin"], "Time": ["Years", "Months", "Weeks", "Days", "Hours", "Minutes", "Seconds", "Millisconds", "Microseconds", " Nanoseconds"], "Volume": ["Cupic Feet","Cubic Meter", "Gallon (Imp)", "Gallon (US)", "Quart (US)", "Pint (US)", "Fluid Oz", "Cup", "Tablespoon", "Teaspoon", "Dram (US)", "Liter"], "Weight": ["Short Ton (US)","Long Ton (UK)", "Pound (U.S)", "Ounce (US)", "Stone", "Metric Ton", "Kilogram", "Gram"]] 
    mainPickerData = dataDict.allKeys as NSArray!; 
    leftRightPickerData = dataDict.object(forKey: mainPickerData.firstObject as! String) as! NSArray 

    // Linking the textFields with the pickerViews. 
    //textFieldLeft.inputView = leftPicker; 
    // textFielfRight.inputView = rightPicker; 



    } 



// The number of columns of data 
func numberOfComponents(in pickerView: UIPickerView) -> Int { 
    return 1 
} 

// The number of rows of data 
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { 

    switch (pickerView.tag) { 

    case mainPicker.tag: 

     return mainPickerData.count 

    case leftPicker.tag,rightPicker.tag: 

     let currentSelectedIndex = mainPicker.selectedRow(inComponent: component) 
     leftRightPickerData = (dataDict.object(forKey: mainPickerData[currentSelectedIndex] as! String) as! NSArray) 

     return leftRightPickerData.count; 

    default: 
     break; 
    } 
    return 0; 
} 

// The data to return for the row and component (column) that's being passed in 
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { 

    if leftPicker.tag == 2 { 

     return leftPickerData[row] 

    }else if rightPicker.tag == 3{ 

     return rightPickerData[row] 

    } 

    return "" 
} 

// Catpure the picker view selection 
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 
    // This method is triggered whenever the user makes a change to the picker selection. 
    // The parameter named row and component represents what was selected. 

    if(pickerView.tag == 1){ 

     let currentSelectedIndex = mainPicker.selectedRow(inComponent: component) 
     leftRightPickerData = (dataDict.object(forKey: mainPickerData[currentSelectedIndex] as! String) as! NSArray) 

     leftPicker.reloadAllComponents() 
     rightPicker.reloadAllComponents() 

     if mainPicker.tag == mainPicker.selectedRow(inComponent: component) { 

      if leftPicker.tag == leftPicker.selectedRow(inComponent: component) && rightPicker.tag == rightPicker.selectedRow(inComponent: component){ 

       textFieldLeft.text = textFielfRight.text 
      } 
     } 

    } 



} 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

    self.view.endEditing(true) 

} 

func textFieldShouldReturn(_ textField: UITextField) -> Bool { 

    textFieldLeft.resignFirstResponder() 
    textFielfRight.resignFirstResponder() 

    return true 

} 

func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? { 

    let titleData : String? 
    if(pickerView.tag == mainPicker.tag){ 
     titleData = mainPickerData[row] as? String; 

    } 
    else{ 

     let currentSelectedIndex = mainPicker.selectedRow(inComponent: 0) 
     leftRightPickerData = (dataDict.object(forKey: mainPickerData[currentSelectedIndex] as! String) as! NSArray) 

     titleData = leftRightPickerData[row] as? String; 
    } 

    let myTitle = NSAttributedString(string: titleData!, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 12.0)!,NSForegroundColorAttributeName:UIColor.blue]) 
    return myTitle; 

} 

}

ответ

0

Я дам вам несколько советов:

  1. Значение в текстовом поле является строкой, вы должны преобразовать его в Double, а затем умножить на другое значение между двумя единицами.
  2. Для сохранения этих разных значений у меня есть идея: сохранить [1, 1760, 5280, 63360, 1.609344, 1609.344, 160934.4, 1609344] для [«Миля», «Двор», «Нога», «Дюйм», «Километр», «Метр», «Сантиметр», «Миллиметр»], затем выполните некоторые математические вычисления.
  3. Вы должны прослушать уведомление UITextFieldTextDidChange для каждого UITextField, чтобы мгновенно вычислить равное значение.

Если вы ленивый разработчик, я нашел, что это для вас: https://github.com/michalkonturek/MKUnits

Надеется, что это помогает.

0

Я хотел бы сделать что-то вроде этого в качестве примера для различных значений длины:

Вы хотели бы сохранить какое-то массив, который отслеживает значение преобразования для каждого из различных единиц измерения, лучший универсальный блок длины метров.Было бы неплохо, чтобы убедиться, что соответствующее значение для каждого блока остается статичным, поэтому создать enum:

enum Length: Int { 
    case mile   = 0 
    case yard   = 1 
    case foot   = 2 
    case inch   = 3 
    case kilometer  = 4 
    // ... keep going with all lenght units of measurement 
} 

Затем вы должны сделать свой массив значений для преобразования, это массив двойных, основанный на значения длины I перечислены в enum выше для преобразования в meters:

// Store values with corresponding indicies in array to the Length enum's values 
let meterConversions:[Double] = [1609.34, 0.9144, 0.3048, 0.0254, 1,000] 

// Store values of length unit descriptions to print after conversion in TextField, long hand or short hand whatever you prefer. (this is optional) 
let lengthUnits = ["Mile", "Yard", "Foot", "Inch", "Kilometer"] 

Затем создайте некоторые методы преобразования:

// Convert length type to meters 
func convertToMeters(type: Length, unitValue: Double) -> Double { 
    return (meterConversions[type.rawValue] * unitValue) 
} 

// Convert meters back to length type 
func convertFromMeters(type: Length, meterValue: Double) -> Double { 
    return meterValue/meterConversions[type.rawValue] 
} 

// Convert from length type to other length type 
func convertType(from: Length, to: Length, unitValue: Double) -> Double { 

    // Convert from value to meters to start 
    let fromValueToMeters:Double = convertToMeters(type: from, unitValue: unitValue) 

    // Now use that value to convert back to desired unit 
    let newUnitValue:Double = convertFromMeters(type: to, meterValue: fromValueToMeters) 

    return newUnitValue 
} 

Затем, когда пользователь выбирает новую строку в левой или правой UIPickerView, обновлять вычисления и обрабатывать ее, однако, вы хотите:

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { 

    // Make sure there is actually some text in the left text field, otherwise return 
    guard let text = textFieldLeft.text else { print("textFieldLeft doesn't contain any text"); return } 

    // You are going to need a numerical (Double) value from the user's text 
    let stringAsDouble = Double(text) 

    // Now check that the text was actually a numerical value able to be converted to a double 
    if let value = stringAsDouble { 

     var typeA:Length! 
     var typeB:Length! 

     if pickerView == leftPicker { 
      typeA = Length(rawValue: row)! 
      typeB = Length(rawValue: rightPicker.selectedRow(inComponent: 0))! 
      converted = convertType(from: typeA, to: typeB, unitValue: value) 
     } 
     else if pickerView == rightPicker { 
      typeA = Length(rawValue: leftPicker.selectedRow(inComponent: 0))! 
      typeB = Length(rawValue: row)! 
      let value:Double = 0 // Determine user entered value from textField 
      converted = convertType(from: typeA, to: typeB, unitValue: value) 
     } 

     updateValueAfterConversion(originalValue: value, originalType: typeA, convertedValue: converted, convertedType: typeB) 
    } else { 
     print("Couldn't convert text to double value") 
    } 
} 

func updateValueAfterConversion(originalValue: Double, originalType: Length, convertedValue: Double, convertedType: Length) { 
    // Update text in both fields, lengthUnits part is optional if you want to print unit along with value. 
    // Update text on left side 
    textFieldLeft.text = "\(originalValue) \(lengthUnits[originalType.rawValue])" 
    // Update text on right side 
    textFieldRight.text = "\(convertedValue) \(lengthUnits[convertedType.rawValue])" 
} 
+0

Что вы имеете в виду для последнего комментария: // Теперь делать все вы хотите с преобразованным значением –

+0

@Turki M. Alsayed - тогда у вас будет введенное значение, преобразованное из типа устройства в pickerA в тип единицы в pickerB. Так что скажем, пользователь запросил конвертацию 10 футов в дюймы. Ваша переменная 'convert' должна иметь значение' 120.0' - вы могли бы затем обновить 'UITextField' или любой другой ярлык, который вы хотите использовать для обновления пользовательского интерфейса, чтобы предупредить пользователя о преобразованном значении. Например: 'textField.text =" Преобразованное значение: \ (преобразованное) "или если это метка: label.text = Преобразованное значение: \ (преобразованное)" и т. Д. – Pierce

+0

Привет, мистер Пирс, Я сделал то, что вы объяснили выше, я сделал только для «ДЛИНЫ», чтобы убедиться, что я иду по правильному пути. К сожалению, когда я выбираю любую вещь из subLength ex: inch, я получил «Nan» в текстовом поле слева и справа. Я сделал следующее: Ваше сотрудничество высоко ценится. если (текстFieldLeft.text? .isEmpty)! { textFieldLeft.text = "\ (конвертированы)" } еще { textFielfRight.text = "\ (конвертированы)" } –