试图在2个UITextFields的计算中增加一个百分比

时间:2019-05-11 17:00:27

标签: swift

我正在使用Swift 5,我是一个相对较新手,在60岁时自学成才,很难得到答案,但是在这里-我有2个文本字段,一个值已经从另一个视图控制器传递了,那么我有一个Item费用字段和计算这些字段的按钮,确定工作正常,但是我想要做的是有另一个文本字段条目,我可以添加一个标记百分比,例如,文本字段1有50,文本字段2我输入3,然后我想添加一个标记值,例如4%,因此当我计算这些字段时,我会得到一个总数加上所添加的标记百分比

我可以使用所有功能,但是找不到添加讨厌的标记的方法

import UIKit

class CostingsViewController: UIViewController {

    //Item Cost entered into this field
    @IBOutlet weak var itemCost: UITextField!
    //Markup value entered into here
    @IBOutlet weak var markUP: UITextField!
    //This value is passed to this viewcontroller from another veiwcontroller
    @IBOutlet weak var newLabel: UILabel!
    //This value is calculated on the IBAction
    @IBOutlet weak var totalCost: UITextField!
    var finalName = ""

    override func viewDidLoad() {
        super.viewDidLoad()

     newLabel.text = finalName

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

    @IBAction func calculateCost(_ sender: Any) {
       //Enter the markUP calculation here



        totalCost.text = String(format: "%.2f",Double(newLabel.text!)! * Double(itemCost.text!)!)

      self.view.endEditing(true)
    }
}
 
totalCost.text = String(format: "%.2f",Double(newLabel.text!)! * Double(itemCost.text!)!) 

这很好用,但是标记我似乎无法正常工作-我已经检查了很多教程,但似乎有很多方法,但都不适合我尝试的方法

3 个答案:

答案 0 :(得分:0)

如果你能说

totalCost.text = String(format: "%.2f",Double(newLabel.text!)! * Double(itemCost.text!)!) 

那么你可以说

let v1 = Double(newLabel.text!)!
let v2 = Double(itemCost.text!)!
let v3 = // do your math here
totalCost.text = String(format: "%.2f", v3)

我不宽容您的密码;我只是说,将它分成几部分应该没有任何困难,以便您可以更轻松地操纵Double值。

答案 1 :(得分:0)

在数学上,您想要将from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtPrintSupport import * from account_class import Account from database_class import Database as db import os import sys import time """ MAIN WINDOW """ class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) #initial load of existing profiles DB = db('accounts_data.db') DB.db_connect() profiles = DB.get_profiles_list() #Communication with the chid window self.dialog = Add_New_Profile_Dialog() self.load_profiles_list(profiles) def load_profiles_list(self, profiles): layout = QVBoxLayout() #profiles added to GUI for profile in self.profiles: #print(profile[0]) profile_layout = QHBoxLayout() profile_label = QLabel() profile_label.setText(str(profile[0])) btn = QPushButton("Launch") self.create_horizontal_layout(profile[0], profile[1], 'Proxy Name') scrollLayout.addWidget(self.horizontalGroupBox) container = QWidget() container.setLayout(layout) print("from load_profile") self.setCentralWidget(container) """Function called from child window to update the profile list of gui with newly added profile""" def update_profiles_list(self): DB = db('accounts_data.db') DB.db_connect() profiles = DB.get_profiles_list() self.load_profiles_list(profiles) print("check from update_profiles_list") return """Child window when new profile is inserted""" class ChildWidowDialog(QMainWindow): def save_profile_db(self): #Adding new data to Database DB = db('accounts_data.db') DB.db_connect() DB.add_profile(profile_name, device_selected, os_browser[1], os_browser[0], proxy) #function from main window called to update profile MainWindow().update_profiles_list() self.close() if __name__ == '__main__': app = QApplication(sys.argv) app.setApplicationName("Profiles") window = MainWindow() app.exec_() 添加到一个值,这意味着将其乘以4%

这意味着:

1.04

请注意,请使用let itemCost = Double(itemCost.text!)! let markUp = Double(markUP.text!)! let total = itemCost * (1 + markUp / 100) totalCost.text = String(format: "%.2f", total) 将数字转换为字符串,反之亦然,特别是在我们谈论货币时。

答案 2 :(得分:0)

总计的计算方式为:

// the total, not rounded (e.g. if there was one item at a unit price of 0.10 and 3% markup (i.e. 0.03), this `unrounded` will have 0.103)

let unrounded = Double(quantity) * unitPrice * (markUp + 1.0) 

// You might then round that value to two decimal places, like so:

let grandTotal = (unrounded * 100.0).rounded(.toNearestOrAwayFromZero) / 100.0

话虽如此,我还建议其他一些事情:

  1. 您可能会注意到,在上面,我没有引用UIKit控件,例如文本字段和标签。您真的想在“模型”(价格,数量,总计等)和“视图”(文本字段,标签等)之间划定界限。

    • 通常,视图对象按照约定包括后缀,以指示视图对象的类型。因此,您可能拥有markUpTextFieldquantityLabel。这样,您不仅不会将它们与相应的模型值混淆,而且可以清楚地知道它是哪种对象。

    • 在更新文本字段时,应该更新模型。例如。更改markUpTextField时,将更新markUp数字模型对象。

    • 在计算总数时,应仅从模型对象进行计算。您不应引用任何UIKit对象。

    这并不是绝对严格的要求,但是这是一个极好的习惯,因为它是MVC(以及MVVM和MVP和...)编程模式的核心原则。当您最终开始使用表/集合视图时,这种好处真正发挥了作用,在该视图中,您的UIKit控件被重用于可见项,而不再是可靠的信息源。当您开始进行代码的单元测试时,它将业务逻辑从视图控制器中拉出,并将它们移至诸如“视图模型”之类的中介对象中,这也将非常有用。

    < / li>
  2. 您应该避免使用String(format:)为UI创建字符串。而是使用NumberFormatter。那解决了两个问题:

    • 您要在UI中接受并生成“本地化”数字。例如,在德国,他们将1.000.000,00写成一百万至小数点后两位。在印度,它可以是10,00,000.00。等等。通过使用NumberFormatter,您可以减少处理所有这些国际格式所需的编码量。

    • 如果您将NumberFormatternumberStyle的{​​{1}}用作标记值,它将为您做必要的除以.percent的操作。

    • p>
  3. 您可能希望将100对象中的delegate设置为您的视图控制器(可以在IB或以编程方式进行操作),然后拥有一个UITextField视图控制器的扩展名,其UITextFieldDelegate仅在使用上述格式器将结果文本更改为数字后才能接受更改。

    您可能还需要一个shouldChangeCharactersIn来在用户完成操作后很好地格式化输入的值。


反映上述观察结果,您得到的结果如下:

textFieldDidEndEditing

进一步完善:创建数据类型以保留价格时,建议不要使用诸如class CostingsViewController: UIViewController { // MARK: Outlets @IBOutlet weak var quantityLabel: UILabel! @IBOutlet weak var priceTextField: UITextField! @IBOutlet weak var markUpTextField: UITextField! @IBOutlet weak var totalLabel: UILabel! // MARK: Model objects var quantity: Int? { didSet { updateTotal() } } var price: Double? { didSet { updateTotal() } } var markUp: Double? { didSet { updateTotal() } } var total: Double? { didSet { totalLabel.text = priceFormatter.string(for: total) } } // MARK: Private formatters private var priceFormatter: NumberFormatter = { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.minimumFractionDigits = 2 formatter.maximumFractionDigits = 2 return formatter }() private var quantityFormatter: NumberFormatter = { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 0 return formatter }() private var percentFormatter: NumberFormatter = { let formatter = NumberFormatter() formatter.numberStyle = .percent formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 2 return formatter }() override func viewDidLoad() { super.viewDidLoad() // I'm going to set these here, but maybe these were supplied by the presenting view controller quantity = 3 price = 1000 markUp = 0 // update the UI controls quantityLabel.text = quantityFormatter.string(for: quantity) priceTextField.text = priceFormatter.string(for: price) markUpTextField.text = percentFormatter.string(for: markUp) totalLabel.text = priceFormatter.string(for: total) } } private extension CostingsViewController { private func updateTotal() { // calculate total let quant = quantity ?? 0 let cost = price ?? 0 let percent = markUp ?? 0 let unrounded = Double(quant) * cost * (percent + 1.0) // round the result let rounded = (unrounded * 100.0).rounded(.toNearestOrAwayFromZero) / 100.0 // update our model total = rounded } } extension CostingsViewController: UITextFieldDelegate { func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // some useful constants let decimalSeparator = priceFormatter.decimalSeparator ?? "." let percentSymbol = percentFormatter.percentSymbol ?? "%" // figure out what the string value will be after replacing the characters let oldText = textField.text ?? "" let updateRange = Range(range, in: oldText)! let text = oldText.replacingCharacters(in: updateRange, with: string).filter(("01234567890" + decimalSeparator).contains) // update the appropriate model object switch textField { case priceTextField: if text == "" { price = 0 return true } else if let value = priceFormatter.number(from: text)?.doubleValue { price = value return true } else { return false } case markUpTextField: if text == "" { markUp = 0 return true } else if let value = percentFormatter.number(from: text + percentSymbol)?.doubleValue { markUp = value return true } else { return false } default: return true } } func textFieldDidEndEditing(_ textField: UITextField) { switch textField { case priceTextField: textField.text = priceFormatter.string(for: price) case markUpTextField: textField.text = percentFormatter.string(for: markUp) default: break } } } Float之类的二进制浮点。这些类型实际上不能完美地捕获小数十进制值。我改用Double类型。如果您开始添加许多二进制浮点值,这将有助于避免舍入问题。

如果这样做,最终会得到以下结果:

Decimal

最后,正如我在上面提到的,我们通常希望从视图控制器中获取很多代码(使用MVVP或MVP或其他方法)。这超出了这个问题的范围,但是为了完整起见,我提到它。