我正在使用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!)!)
这很好用,但是标记我似乎无法正常工作-我已经检查了很多教程,但似乎有很多方法,但都不适合我尝试的方法
答案 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
话虽如此,我还建议其他一些事情:
您可能会注意到,在上面,我没有引用UIKit控件,例如文本字段和标签。您真的想在“模型”(价格,数量,总计等)和“视图”(文本字段,标签等)之间划定界限。
通常,视图对象按照约定包括后缀,以指示视图对象的类型。因此,您可能拥有markUpTextField
或quantityLabel
。这样,您不仅不会将它们与相应的模型值混淆,而且可以清楚地知道它是哪种对象。
在更新文本字段时,应该更新模型。例如。更改markUpTextField
时,将更新markUp
数字模型对象。
在计算总数时,应仅从模型对象进行计算。您不应引用任何UIKit
对象。
这并不是绝对严格的要求,但是这是一个极好的习惯,因为它是MVC(以及MVVM和MVP和...)编程模式的核心原则。当您最终开始使用表/集合视图时,这种好处真正发挥了作用,在该视图中,您的UIKit控件被重用于可见项,而不再是可靠的信息源。当您开始进行代码的单元测试时,它将业务逻辑从视图控制器中拉出,并将它们移至诸如“视图模型”之类的中介对象中,这也将非常有用。
< / li>您应该避免使用String(format:)
为UI创建字符串。而是使用NumberFormatter
。那解决了两个问题:
您要在UI中接受并生成“本地化”数字。例如,在德国,他们将1.000.000,00
写成一百万至小数点后两位。在印度,它可以是10,00,000.00
。等等。通过使用NumberFormatter
,您可以减少处理所有这些国际格式所需的编码量。
如果您将NumberFormatter
和numberStyle
的{{1}}用作标记值,它将为您做必要的除以.percent
的操作。
您可能希望将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或其他方法)。这超出了这个问题的范围,但是为了完整起见,我提到它。