【问题标题】:NSTextFields using bindings not updating after initialization使用绑定的 NSTextFields 在初始化后不更新
【发布时间】:2016-10-31 16:58:38
【问题描述】:

我正在从 JSON 导入数据以用作 CollectionView 中某些项目的模型,并且似乎它们正在被初始化,并且具有正确数量的元素。但由于某种原因,representedObject(下面别名为morpheme)最初返回nil。因此,如果 nil 值出现,则占位符。

如果您单击项目,我已将其设置为在日志中显示所单击项目的名称,并且工作正常,并且不会返回调试默认值。所以我猜有一个并发问题。

有关更多详细信息,这是手动原型化的项目,因为 XCode 7 仍未修复集合项目原型的 segue 错误。

这是一个截图,我希望能在其中获取所有重要信息:

这里是单元格的控制器/委托类的详细代码:

///Acts as view controller for the items of the morpheme collection
public class MorphemeCell: NSCollectionViewItem, NSTextViewDelegate{

    var backgroundColor = NSColor.clearColor()

    var morphemeLabel: String{
        get{
            return morpheme?.morphemeDisplayName ?? "Morpheme"
        }
    }

    var allomorphsLabel: String{
        get{
            return (morpheme?.allomorphsAsString ?? "Allomorphs")
        }
    }

    ///The morpheme data contained in the cell
    public var morpheme : Morpheme?{
        get{
            return representedObject as? Morpheme
        }
        set{
            representedObject = newValue
        }
    }

    required public init?(coder: NSCoder) {
        super.init(coder: coder)
    }

    ///Detects clicks on each item
    public override func mouseUp(theEvent: NSEvent) {
        Swift.print("Clicked on " + morphemeLabel)
        backgroundColor = NSColor.blueColor()
    }
}

不确定是否需要这样做,但以防万一主窗口的 ViewController 正在执行一些设置/加载功能。

加载代码本身:

///Loads morpheme data into memory and then into the collection view
func loadMorphemeData(){
    //Open morphemes.json and begin parsing
    let morphemeDataPath = "morphemes"
    if let file = NSBundle.mainBundle().URLForResource(morphemeDataPath, withExtension: "json")
    {
        let data = NSData(contentsOfURL: file)
        let json = JSON(data:data!)

        //Create Morpheme objects passing in JSON elements
        for morphemeElement in json{
            let toAdd = Morpheme(JSONElement: morphemeElement)
            fullMorphemesList.append(toAdd)
        }
        ///TODO Use full range or filters in final product
        let morphemesToLoad = fullMorphemesList[0...100]
        collectionView.content.appendContentsOf(Array(morphemesToLoad) as [AnyObject])
    }
    else
    {
        print("Resource Failure")
    }

所以,回顾一下:看来我要么需要延迟 collectionView 的设置,要么找出数据进入后如何更新标签。 非常感谢您的帮助!我对 Cocoa 框架很陌生,所以它很笨拙。

【问题讨论】:

  • 贴代码,不是截图
  • 属性是否符合 KVO?
  • 啊,哎呀,我太忙于 UI 的注释,以至于忘记了代码。我已经更新了它。我不完全确定。我对框架非常陌生,所以我还不能查看 KVO 合规性。我猜这是实时绑定的首选方法?

标签: xcode swift cocoa swift2 cocoa-bindings


【解决方案1】:

采取不同的方式:将您的标签绑定到 self.morpheme.morphemeDisplayName。然后将“Null Placeholder”文本设置为“Morpheme”(在该右侧面板中,请参阅绑定设置下方的文本编辑列表)。最后使属性morphemeDisplayName动态化:

 dynamic var morphemeDisplayName: String? 

显然,您不再需要单元格内的 morphemeLabel 属性。

cell的语素属性也必须是动态的,或者如果有基于setter的属性,你可以调用:

 set {
 willChangeValueForKey("morpheme") 
 <whatever variable> = newValue 
 didChangeValueForKey("morpheme") 
 }

由原始海报编辑:

另外,为了避免绑定同步问题,使用viewWillAppear() 而不是viewDidLoad() 会导致数据加载和“冻结标签”问题。

【讨论】:

  • 为了做到这一点,我转到检查器的绑定部分,选择 CollectionItem(在本例中为 MorphemeCell)作为模型,并使用 morphemeDisplayName 的路径作为“模型键”小路'?另外,对于will/didChangeValueForKey(String) 函数,我是只输入模型/控制器的属性,还是必须在某处显式创建一个键?
  • 好吧,现在你的属性“morphemeDisplayName”在 Morpheme 类中(你应该在那里创建它),你的“模型键路径”将是 self.morpheme.morphemeDisplayName(有点钻到对象等级制度)。对于第二部分,您已经拥有财产。装饰一下: public var morpheme : Morpheme?{ get{ return mappedObject as? Morpheme } set{ willChangeValueForKey("morpheme")代表Object = newValue didChangeValueForKey("morpheme") } }
  • 非常感谢!看起来它正在正常工作并显示正确! (不过大约有一半的时间,所以看起来我需要重温并发性以避免发生可能的竞争条件。)
  • 当您在代码中设置属性并且这些属性是数据绑定时,请确保您在主队列中执行此操作。将 jSOn 传递给 NSOperationQueue.mainQueue().addOperationWithBlock { your code } 后,您需要移动该代码
猜你喜欢
  • 2018-04-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多