在Swift中将属性绑定到NSTextFields [英] Bind properties in Swift to NSTextFields

查看:307
本文介绍了在Swift中将属性绑定到NSTextFields的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Swift编写的单位转换器,它会自动在相应的 NSTextField 中显示更新的单位。对于此示例,如果用户在 minutesField 中输入分钟,则 secondsField hoursField 应自动更新以显示属性中转换的值。下面是我的视图控制器中的代码示例:

I'm working on a unit converter written in Swift that will automatically display the updated units within the appropriate NSTextFields. For this example, if the user inputs minutes into the minutesField, the secondsField and hoursField should automatically update to display the converted values from the properties. Below is an example of the code in my view controller:

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 出现在第一个关键笔划之后(见下图)。这可能是由于在属性更新后调用的函数。属性根据活动文本字段的标记进行更新。

The code above updates the text fields but the active field with the input freezes after the first key stroke. For example, if you try to enter 60 into the seconds field, the next key stroke does not do anything. The number 6.0 appears after the first key stroke (see image below). This is likely due to the function that is called after the properties are updated. The properties are updated based on the tag of the active text field.

可以有一个函数来更新除当前活动字段之外的所有其他文本字段?

Is it possible to have a function that will update all the other text fields other than the currently active field?

推荐答案


可以有一个函数来更新除当前活动字段之外的所有其他文本
字段吗?

Is it possible to have a function that will update all the other text fields other than the currently active field?

是的。您可以将所有文本字段连接到相同的操作。

Yes. You can connect all text field to the same action.

首先将所有文本字段相应地连接到您的视图控制器:

First connect all your text fields accordingly to your view controller:

@IBOutlet weak var hourField: NSTextField!
@IBOutlet weak var minuteField: NSTextField!
@IBOutlet weak var secondField: NSTextField!

第二个创建一个var来表示你的时间间隔。你还可以添加一个setter / getter来自动存储到NSUSerDefaults:

Second create a single var to represent your time interval. You can also add a setter / getter to store it automatically to NSUSerDefaults:

var timeInterval: NSTimeInterval {
    get {
        return NSUserDefaults().doubleForKey("timeInterval")
    }
    set {
        NSUserDefaults().setDouble(newValue, forKey: "timeInterval")
    }
}

再次创建一个NSTimeInterval扩展,将时间从秒转换为小时/ p>

Third create a NSTimeInterval extension to convert the time from seconds to hour/minute

extension NSTimeInterval {
    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 }
}

第四个创建将更新其他文本字段的操作:

Fourth create the action that will update the other text fields:

@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
    }
}

最后,确保在下次您的视图显示时加载值:

Last but not least make sure you load the values next time your view will appear:

override func viewWillAppear() {
    hourField.stringValue = timeInterval.hour.description
    minuteField.stringValue = timeInterval.minute.description
    secondField.stringValue = timeInterval.second.description
}


$ b b

示例项目

这篇关于在Swift中将属性绑定到NSTextFields的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆