我正在研究用Swift编写的单位转换器,它会在适当的NSTextField
s内自动显示更新的单位。对于此示例,如果用户在minutesField
中输入分钟,则secondsField
和hoursField
应自动更新以显示属性中的转换值。下面是我的视图控制器中的代码示例:
import Cocoa
class ViewController: NSViewController {
@IBOutlet weak var secondsField: NSTextField!
@IBOutlet weak var minutesField: NSTextField!
@IBOutlet weak var hoursField: NSTextField!
var sec: Double = 1
var min: Double = 1
var hr: Double = 1
let conv = [[1, 0.0166666666666667, 0.000277777777777778],
[60, 1, 0.0166666666666667],
[3600, 60, 1]]
func updateTextFields() {
secondsField.stringValue = "\(sec)"
minutesField.stringValue = "\(min)"
hoursField.stringValue = "\(hr)"
}
}
extension ViewController: NSTextFieldDelegate {
override func controlTextDidChange(obj: NSNotification) {
let tag = obj.object?.tag() ?? 0
let text = obj.object?.stringValue ?? "1"
let value = Double(text) ?? 1.0
switch tag {
case 0:
// base unit = seconds
sec = value
min = value * conv[0][1]
hr = value * conv[0][2]
case 1:
// base unit = minutes
sec = value * conv[1][0]
min = value
hr = value * conv[1][2]
case 2:
// base unit = hours
sec = value * conv[2][0]
min = value * conv[2][1]
hr = value
default:
"none"
}
updateTextFields()
}
}
上面的代码更新了文本字段,但是第一个按键后输入冻结的活动字段。例如,如果您尝试在秒字段中输入60
,则下一个键击不会执行任何操作。第一个击键后出现数字6.0
(见下图)。这可能是由于在更新属性后调用的函数。根据活动文本字段的标记更新属性。
是否可以使用一个函数来更新当前活动字段以外的所有其他文本字段?
答案 0 :(得分:0)
您需要移动文本字段的设置' seconds
之外的值到单独的方法。从secondsField.floatValue
以及{{1}}属性上的{{1}}属性观察者调用该方法。
您还需要为更改秒,分钟或小时字段时创建操作方法。在秒字段的操作方法中,将{{1}}属性设置为{{1}}。对于其他两个领域也是如此。在NIB /故事板中,连接文本字段'对视图控制器上相应操作方法的操作。
答案 1 :(得分:0)
是否可以使用更新所有其他文本的功能 当前活动字段以外的字段?
是。您可以将所有文本字段连接到同一操作。
首先将所有文本字段相应地连接到视图控制器:
@IBOutlet weak var hourField: NSTextField!
@IBOutlet weak var minuteField: NSTextField!
@IBOutlet weak var secondField: NSTextField!
第二次创建一个var来表示您的时间间隔。您还可以添加setter / getter以将其自动存储到USerDefaults:
var timeInterval: TimeInterval {
get {
return UserDefaults.standard.double(forKey: "timeInterval")
}
set {
UserDefaults.standard.set(newValue, forKey: "timeInterval")
}
}
第三步创建一个TimeInterval扩展名,将时间从秒转换为小时/分钟
extension TimeInterval {
var second: Double { return self }
var minute: Double { return self / 60 }
var hour: Double { return self / 3600 }
var hourToMinute: Double { return self * 60 }
var hourToSecond: Double { return self * 3600 }
var minuteToHour: Double { return self / 60 }
var minuteToSecond: Double { return self * 60 }
}
第四步创建将更新其他文本字段的操作:
@IBAction func timeAction(sender: NSTextField) {
// use guard to convert the field string to Double
guard let time = Double(sender.stringValue) else { return }
// switch the field
switch sender {
case hourField:
// convert / update secondary fields
minuteField.stringValue = time.hourToMinute.description
secondField.stringValue = time.hourToSecond.description
// make it persist through launches
timeInterval = time * 3600
case minuteField:
hourField.stringValue = time.minuteToHour.description
secondField.stringValue = time.minuteToSecond.description
timeInterval = time * 60
default:
hourField.stringValue = time.hour.description
minuteField.stringValue = time.minute.description
timeInterval = time
}
}
最后但并非最不重要的是确保您下次出现视图时加载值:
override func viewWillAppear() {
hourField.stringValue = timeInterval.hour.description
minuteField.stringValue = timeInterval.minute.description
secondField.stringValue = timeInterval.second.description
}