Вычислить уравнение в Swift - PullRequest
0 голосов
/ 05 января 2020

Привет всем. Я довольно новичок в Swift, и у меня есть приложение, в котором мне нужно получить пользовательский ввод и поместить его в уравнение для отображения на другом контроллере представления. У меня возникли проблемы при вводе этого уравнения следующим образом ...

masterMix.waterVolumeLabel.text = numberOfSamplesTextField (50 - dNTPsVolumeLabel.text - forwardPrimerLabel.text - reversePrimerLabel.text - dnaPolymeraseLabel.texterBabliteTexteteBeteteteteteteteTeteteteteTeteteteTeBte: --TMBTTEFTELEBTEFTELEBTEFTELEBTELTELTELTELTELTEFTELFELTEFTELTEFF - )

Общая сумма из скобок должна быть умножена на numberOfSamplesTextField

Как мне написать это в swift? Уравнение внутри подготовить к переходу.

import UIKit

class SelectAttributesViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {

    @IBOutlet weak var kitPickerView: UIPickerView!
    @IBOutlet weak var reactionVolumeLabel: UILabel!
    @IBOutlet weak var numberOfSampleTextField: UITextField!
    @IBOutlet weak var volumeOfTemplateDNATextField: UITextField!
    @IBOutlet weak var slider: UISlider!
    @IBOutlet weak var calculateButton: UIButton!






    let kits = ["kit 1", "Kit 2"]
    let pArray = [10,20,50]

    override func viewDidLoad() {
        super.viewDidLoad()
        self.numberOfSampleTextField.delegate = self
        self.volumeOfTemplateDNATextField.delegate = self
        kitPickerView.dataSource = self
        kitPickerView.delegate = self

        //slider.addTarget(self, action: "reactionVolumeSlider", for: .valueChanged)

        let tap = UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:)))
        view.addGestureRecognizer(tap)

        // Do any additional setup after loading the view.
    }

    func pInterval() {
        slider.minimumValue = 0
        slider.maximumValue = Float(pArray.count)
        slider.isContinuous = false

    }


    @IBAction func reactionVolumeSlider(_ sender: UISlider) {
        print(Int(sender.value))
        let currentValue = pArray[Int(sender.value)]
        reactionVolumeLabel.text = "\(currentValue) μL"


    }
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return kits.count

    }
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        if row == 0{ print(kits[row])

        }else if row == 1{
            createAlert(title: "Kit not available", message: "More kits will be added soon!")
            calculateButton.isEnabled = false
        }

    }
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return kits[row]
    }
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let oldText = textField.text, let r = Range(range, in: oldText) else {
            return true
        }

        let newText = oldText.replacingCharacters(in: r, with: string)
        let isNumeric = newText.isEmpty || (Double(newText) != nil)
        let numberOfDots = newText.components(separatedBy: ".").count - 1

        let numberOfDecimalDigits: Int
        if let dotIndex = newText.firstIndex(of: ".") {
            numberOfDecimalDigits = newText.distance(from: dotIndex, to: newText.endIndex) - 1
        } else {
            numberOfDecimalDigits = 0
        }

        return isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 2
    }
    func createAlert (title: String, message: String){
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: { (Action) in
            alert.dismiss(animated: true, completion: nil)
        }))
        self.present(alert, animated: true, completion: nil)

    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        let masterMix = segue.destination as! MasterMixTableViewController
        masterMix.loadViewIfNeeded()

       // The line below is where I tried to implement this function
       // masterMix.waterVolumeLabel!.text = 


        masterMix.bufferVolumeLabel.text = String(Double(numberOfSampleTextField.text!)! * 10)
        masterMix.dNTPsVolumeLabel.text = numberOfSampleTextField!.text // done
        masterMix.forwardPrimerLabel.text = String(Double(numberOfSampleTextField.text!)! * 2.5) //done
        masterMix.reversePrimerLabel.text = String(Double(numberOfSampleTextField.text!)! * 2.5) //done
        masterMix.dnaPolymeraseLabel.text = String(Double(numberOfSampleTextField.text!)! * 0.5) //done

        //answer.text = String(Int(entry.text)! * 2)

    }

    @IBAction func calculatePressed(_ sender: Any) {
        if numberOfSampleTextField.text != ""{
            performSegue(withIdentifier: "masterMixSegue", sender: self)
        }

    }




}

1 Ответ

1 голос
/ 06 января 2020

Есть некоторые проблемы с тем, что вы пытаетесь сделать. Во-первых, вам не следует устанавливать содержимое представления в контроллере представления назначения в prepareForSegue. Вы можете вычислить значение, а затем передать его, как предложил Филипп. Сначала вы должны рассчитать это. Еще одна проблема заключается в том, что вы не можете запускать математические операторы для текста, что, похоже, вы пытаетесь сделать. Вы можете привести String в Int или Double, и он вернется как необязательный на тот случай, если текст на самом деле не содержит числа. Было бы безопаснее всегда условно развернуть, но я думаю, что для вашего случая вы могли бы сделать что-то вроде добавления расширения в String, чтобы вернуть либо необязательное двойное значение текста, либо ноль, если оно равно nil (таким образом, это не не оказывает никакого влияния на результат). Так что добавьте это в свой проект вне каких-либо классов:

extension String {
    func doubleValue() -> Double {
        return Double(self) ?? 0
    }
}

Теперь в вашем первом V C вы можете добавить эту функцию ниже, чтобы сделать свой расчет. Я собираюсь предположить, что вы пропустили некоторый код, потому что в предоставленном вами коде вы не объявили много этих различных меток и textFields (dNTPsVolumeLabel, forwardPrimerLabel и др. c). Итак, если у вас уже есть такие как часть вашего первого V C, что-то вроде этого должно работать нормально:

func getWaterVolumeLabelText() -> String? {
    numberOfSamplesTextField.text?.doubleValue() * (50.0 - dNTPsVolumeLabel.text?.doubleValue() - forwardPrimerLabel.text?.doubleValue() - reversePrimerLabel.text?.doubleValue() - dnaPolymeraseLabel.text?.doubleValue() - volumeOfTemplateDNAtextfield.text?.doubleValue() - bufferVolumeLabel.text?.doubleValue())
}

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

class MasterMixTableViewController: UIViewController{

    // This is would be your label in your destination view controller
    @IBOutlet weak var waterVolumeLabel: UILabel!

    // Add this
    public var waterVolumeText: String?

    override func viewWillAppear(_ animated: Bool) {
        // Here you can do whatever with the passed-in string
        waterVolumeLabel.text = waterVolumeText
    }
}

Теперь go вернуться к методу подготовки к переходу в вашем SelectAttributesViewController и просто изменить это к этому:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let masterMix = segue.destination as! MasterMixTableViewController
    masterMix.loadViewIfNeeded()

    // This will pass the value along
    masterMix.waterVolumeText = getWaterVolumeLabelText()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...