Swift 4:当.count > 3时,如何改变多个UITextFields中数字的字体属性,如何反向计算?
Swift 4: How to change font attributes of number in multiple UITextFields when .count > 3 and how to reverse calculation?
我有三个 UITextField,它们只包含一个介于 0 和最大 13066 或 3915 之间的整数。它带有一种特殊字体,其中 50pt 处的 font1
大于 50pt 处的 font2
,所以我只需要调整字体文件,而不是大小。
1) 我需要帮助找到一种方法,让数百位显示为 font2
,但是当数字 >= 1000 时,千位数字显示为 font1
,而数百人仍然保持font2
。由于这是一个 UITextField 输入,我需要它实时发生。
Animated picture of how the end result eventually will be!
2) 如果您观看动画,您会看到三个字段中的每一个的总和都等于底部的字段。这是直截了当的。然而,我也想扭转这一点,即填写总数,表盘和数字应如图所示填写(每个 MAIN 中的一半高达 3920,其余在 CTR 中高达 13066)。我如何编写这样的功能可逆计算并避免冲突?
这是我目前得到的结果,但还不能完全满足我的要求:
`class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var centerField: UITextField!
@IBOutlet weak var main1Field: UITextField!
@IBOutlet weak var main2Field: UITextField!
@IBOutlet weak var totalField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
//UITextField delegation
centerField.delegate = self
main1Field.delegate = self
main2Field.delegate = self
totalField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//Change font when number input exceeds 3 digits
func getAttributedString(for number: Int) -> NSAttributedString {
let defaultAttributes = [
NSAttributedStringKey.font: UIFont(name: "PMDG_777_DU_A", size: UIFont.labelFontSize)!
]
let bigNumberAttributes = [
NSAttributedStringKey.font: UIFont(name: "PMDG_777_DU_B", size: UIFont.labelFontSize)!
]
let attributedString = NSMutableAttributedString(string: "\(number)", attributes: defaultAttributes)
if attributedString.length > 3 {
let substr = attributedString.string.dropLast(3)
let range = NSMakeRange(0, substr.utf16.count)
attributedString.setAttributes(bigNumberAttributes, range: range)
}
return attributedString
}
//Hide keyboard when hitting Return
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
//Hide keyboard when tapping outside of field
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
//Real-time calculation of entries made to the fields and output it live to the total
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//Convert the String inserted into the fields into Int and create variables
let centerFuel = Int(centerField.text!) ?? 0
centerField.attributedText = getAttributedString(for: centerFuel)
let main1Fuel = Int(main1Field.text!) ?? 0
main1Field.attributedText = getAttributedString(for: main1Fuel)
let main2Fuel = Int(main2Field.text!) ?? 0
main2Field.attributedText = getAttributedString(for: main2Fuel)
let total: Int = centerFuel + main1Fuel + main2Fuel
totalField.attributedText = getAttributedString(for: total)
return true
}
这是一个示例解决方案:
func attributedString(fromIntStr: String) -> NSAttributedString {
print("Working with: \(fromIntStr)")
let finalAttr = NSMutableAttributedString.init()
let length = fromIntStr.count
if length > 3 //we test this because we can't do dropLast(n) where n is negative
{
let start = String(fromIntStr.dropLast(3))
let firstPart = NSAttributedString.init(string: start,
attributes: [.font: UIFont.systemFont(ofSize: 20)])
finalAttr.append(firstPart)
}
var dropEnd = 0
if length > 3 //we test this because we can't do dropFirst(n) where n is negative
{
dropEnd = length - 3
}
else
{
dropEnd = 0 //That's just an explicit value but it was already set by default
}
let end = String(fromIntStr.dropFirst(dropEnd))
let lastPart = NSAttributedString.init(string: end,
attributes: [.font: UIFont.systemFont(ofSize: 15)])
finalAttr.append(lastPart)
//It seems that you want a right alignement and since we are using NSAttributedString we can do it by using ParagraphStyle
let paragraphStyle = NSMutableParagraphStyle.init()
paragraphStyle.alignment = .right
finalAttr.addAttribute(.paragraphStyle,
value: paragraphStyle,
range: NSRange(location: 0, length: finalAttr.length))
return finalAttr
}
可以在 Playground 上测试,最后添加:
let values = ["", "9", "89", "789", "6789", "56789"]
let view = UIView.init(frame: CGRect(x: 0, y: 0, width: 800, height: 400))
for (i, str) in values.enumerated().reversed()
{
let label = UILabel.init(frame: CGRect(x: 0, y: i*50, width: 800, height: 50))
let attr = attributedString(fromIntStr: str)
label.attributedText = attr
view.addSubview(label)
}
view
有多种方法可以做到这一点,但这是我使用的逻辑:
• 创建 NSMutableAttributedString
.
• 将字符串分成两个字符串(一个用于0-999,另一个用于其余部分)
• 用相应的字体
从中创建两个 NSAttributedString
• 将它们附加到之前创建的 NSMutableAttributedString
。
当然可以改进:
dropFirst()
/dropLast()
是最好的解决方案吗?
我假设您已经从 Int
添加了一个 String
值(我没有进行转换)。
另一个更经典的解决方案是:
• 从整个 String
.
创建一个 NSMutableAttributedString
• 在范围 last from last-3
上应用小字体
• 在范围开始到最后应用大字体 -3
如果您在整个字符串的开头应用大字体,则最后一点将被省略。
使用NSMutableAttributedString
:
func getAttributedString(for number: Int) -> NSAttributedString {
precondition(number >= 0)
let defaultAttributes = [
NSAttributedStringKey.font: UIFont.systemFont(ofSize: 18)
]
let bigNumberAttributes = [
NSAttributedStringKey.font: UIFont.systemFont(ofSize: 30)
]
let attributedString = NSMutableAttributedString(string: "\(number)", attributes: defaultAttributes)
if attributedString.length > 3 {
let range = NSMakeRange(0, attributedString.length - 3)
attributedString.setAttributes(bigNumberAttributes, range: range)
}
return attributedString
}
然后在你的标签上设置attributedText
属性:
label.attributedText = getAttributedString(for: 13006)
你可以得到这样的结果:
根据口味调整样式!
我有三个 UITextField,它们只包含一个介于 0 和最大 13066 或 3915 之间的整数。它带有一种特殊字体,其中 50pt 处的 font1
大于 50pt 处的 font2
,所以我只需要调整字体文件,而不是大小。
1) 我需要帮助找到一种方法,让数百位显示为 font2
,但是当数字 >= 1000 时,千位数字显示为 font1
,而数百人仍然保持font2
。由于这是一个 UITextField 输入,我需要它实时发生。
Animated picture of how the end result eventually will be!
2) 如果您观看动画,您会看到三个字段中的每一个的总和都等于底部的字段。这是直截了当的。然而,我也想扭转这一点,即填写总数,表盘和数字应如图所示填写(每个 MAIN 中的一半高达 3920,其余在 CTR 中高达 13066)。我如何编写这样的功能可逆计算并避免冲突?
这是我目前得到的结果,但还不能完全满足我的要求:
`class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var centerField: UITextField!
@IBOutlet weak var main1Field: UITextField!
@IBOutlet weak var main2Field: UITextField!
@IBOutlet weak var totalField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
//UITextField delegation
centerField.delegate = self
main1Field.delegate = self
main2Field.delegate = self
totalField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//Change font when number input exceeds 3 digits
func getAttributedString(for number: Int) -> NSAttributedString {
let defaultAttributes = [
NSAttributedStringKey.font: UIFont(name: "PMDG_777_DU_A", size: UIFont.labelFontSize)!
]
let bigNumberAttributes = [
NSAttributedStringKey.font: UIFont(name: "PMDG_777_DU_B", size: UIFont.labelFontSize)!
]
let attributedString = NSMutableAttributedString(string: "\(number)", attributes: defaultAttributes)
if attributedString.length > 3 {
let substr = attributedString.string.dropLast(3)
let range = NSMakeRange(0, substr.utf16.count)
attributedString.setAttributes(bigNumberAttributes, range: range)
}
return attributedString
}
//Hide keyboard when hitting Return
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
//Hide keyboard when tapping outside of field
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
//Real-time calculation of entries made to the fields and output it live to the total
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
//Convert the String inserted into the fields into Int and create variables
let centerFuel = Int(centerField.text!) ?? 0
centerField.attributedText = getAttributedString(for: centerFuel)
let main1Fuel = Int(main1Field.text!) ?? 0
main1Field.attributedText = getAttributedString(for: main1Fuel)
let main2Fuel = Int(main2Field.text!) ?? 0
main2Field.attributedText = getAttributedString(for: main2Fuel)
let total: Int = centerFuel + main1Fuel + main2Fuel
totalField.attributedText = getAttributedString(for: total)
return true
}
这是一个示例解决方案:
func attributedString(fromIntStr: String) -> NSAttributedString {
print("Working with: \(fromIntStr)")
let finalAttr = NSMutableAttributedString.init()
let length = fromIntStr.count
if length > 3 //we test this because we can't do dropLast(n) where n is negative
{
let start = String(fromIntStr.dropLast(3))
let firstPart = NSAttributedString.init(string: start,
attributes: [.font: UIFont.systemFont(ofSize: 20)])
finalAttr.append(firstPart)
}
var dropEnd = 0
if length > 3 //we test this because we can't do dropFirst(n) where n is negative
{
dropEnd = length - 3
}
else
{
dropEnd = 0 //That's just an explicit value but it was already set by default
}
let end = String(fromIntStr.dropFirst(dropEnd))
let lastPart = NSAttributedString.init(string: end,
attributes: [.font: UIFont.systemFont(ofSize: 15)])
finalAttr.append(lastPart)
//It seems that you want a right alignement and since we are using NSAttributedString we can do it by using ParagraphStyle
let paragraphStyle = NSMutableParagraphStyle.init()
paragraphStyle.alignment = .right
finalAttr.addAttribute(.paragraphStyle,
value: paragraphStyle,
range: NSRange(location: 0, length: finalAttr.length))
return finalAttr
}
可以在 Playground 上测试,最后添加:
let values = ["", "9", "89", "789", "6789", "56789"]
let view = UIView.init(frame: CGRect(x: 0, y: 0, width: 800, height: 400))
for (i, str) in values.enumerated().reversed()
{
let label = UILabel.init(frame: CGRect(x: 0, y: i*50, width: 800, height: 50))
let attr = attributedString(fromIntStr: str)
label.attributedText = attr
view.addSubview(label)
}
view
有多种方法可以做到这一点,但这是我使用的逻辑:
• 创建 NSMutableAttributedString
.
• 将字符串分成两个字符串(一个用于0-999,另一个用于其余部分)
• 用相应的字体
从中创建两个 NSAttributedString
• 将它们附加到之前创建的 NSMutableAttributedString
。
当然可以改进:
dropFirst()
/dropLast()
是最好的解决方案吗?
我假设您已经从 Int
添加了一个 String
值(我没有进行转换)。
另一个更经典的解决方案是:
• 从整个 String
.
创建一个 NSMutableAttributedString
• 在范围 last from last-3
上应用小字体
• 在范围开始到最后应用大字体 -3
如果您在整个字符串的开头应用大字体,则最后一点将被省略。
使用NSMutableAttributedString
:
func getAttributedString(for number: Int) -> NSAttributedString {
precondition(number >= 0)
let defaultAttributes = [
NSAttributedStringKey.font: UIFont.systemFont(ofSize: 18)
]
let bigNumberAttributes = [
NSAttributedStringKey.font: UIFont.systemFont(ofSize: 30)
]
let attributedString = NSMutableAttributedString(string: "\(number)", attributes: defaultAttributes)
if attributedString.length > 3 {
let range = NSMakeRange(0, attributedString.length - 3)
attributedString.setAttributes(bigNumberAttributes, range: range)
}
return attributedString
}
然后在你的标签上设置attributedText
属性:
label.attributedText = getAttributedString(for: 13006)
你可以得到这样的结果:
根据口味调整样式!