NSTokenField使用Swift建议的令牌

时间:2015-11-29 23:07:50

标签: swift autocomplete nstokenfield

我是Swift的新手,来自AppleScript Obj-C。我已经阅读了几本书并且对语法感到满意,但我仍然感到非常迷失。

我试图创建一个简单的令牌字段,它建议自动完成令牌,例如Apple Mail在识别您的联系人中的电子邮件时执行的操作。我的灵感来自this ASOC script (post #6)。我试图尽可能快地复制它(没有令牌上的动作菜单):

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

@IBOutlet weak var window: NSWindow!
@IBOutlet weak var tokenField: NSTokenField!
var theNames = [String]()


func applicationDidFinishLaunching(aNotification: NSNotification) {
    tokenField.setDelegate(tokenField.delegate())
    theNames = ["Pomona", "Potomac", "Potable", "Process", "Plow"]
}

func tokenField(tokenField : NSTokenField, completionsForSubstring substring : String, indexOfSelectedItem selectedIndex : UnsafeMutablePointer<Int>) -> [AnyObject]? {
    var thePredicate = NSPredicate(format: "SELF beginswith[cd] %@", substring)
    var matchingNames = (theNames as NSArray).filteredArrayUsingPredicate(thePredicate)
    return matchingNames as Array
}

func tokenField(tokenField : NSTokenField, hasMenuForRepresentedObject representedObject : AnyObject) -> Bool {
    return true
}


func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
}


}

总结一下。当用户输入时,如果第一个字母是&#34; p&#34;,则菜单包含&#34; Pomona&#34;,&#34; Potomac&#34;,&#34; Potable&#34;,& #34;流程&#34;,&#34;犁&#34;应该弹出这个词的下方。我不确定为什么没有出现。

有什么想法吗?

编辑:

2016年2月13日

在ioquatix下面提供了我的问题的答案,但它超出了我目前的知识水平。他确实指出我原始代码中的一个关键缺陷是缺少NSTokenFieldCellDelegateNSTokenFieldDelegate。感谢他的帮助,我的(简单但有限的)解决方案是:

import Cocoa
@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate, NSTokenFieldCellDelegate, NSTokenFieldDelegate {

    var names = ["Pat", "Pot"]
    @IBOutlet weak var tokenField: NSTokenField!

    func tokenField(tokenField: NSTokenField, completionsForSubstring substring: String, indexOfToken tokenIndex: Int, indexOfSelectedItem selectedIndex: UnsafeMutablePointer<Int>) -> [AnyObject]? {
        return (names as NSArray).filteredArrayUsingPredicate(NSPredicate(format: "SELF beginswith[cd] %@", substring))
    }

}

1 个答案:

答案 0 :(得分:1)

我使用NSTokenFieldDelegate方法实现了自动完成:

import Cocoa
import CoreData

class PMTagCompletionController : NSObject, NSTokenFieldDelegate, NSTokenFieldCellDelegate {
    var managedObjectContext : NSManagedObjectContext?
    var tagEntityName = "Tag"

    func completionsForSubstring(substring : String) -> [String] {
        if let managedObjectContext = self.managedObjectContext {
            let tagEntity: NSEntityDescription? = NSEntityDescription.entityForName(self.tagEntityName, inManagedObjectContext: managedObjectContext)

            let request: NSFetchRequest = NSFetchRequest.init()

            request.entity = tagEntity;

            if let allTags = try! managedObjectContext.executeFetchRequest(request) as? [PMTag] {
                var tagNames : [String] = []

                let lowercaseSubstring: String = substring.lowercaseString

                for tag: PMTag in allTags {
                    if tag.name.lowercaseString.hasPrefix(lowercaseSubstring) {
                        tagNames.append(tag.name)
                    }
                }

                return tagNames
            }
        }

        return []
    }

    func tokenFieldCell(tokenFieldCell: NSTokenFieldCell, completionsForSubstring substring: String, indexOfToken tokenIndex: Int, indexOfSelectedItem selectedIndex: UnsafeMutablePointer<Int>) -> [AnyObject] {
        return self.completionsForSubstring(substring)
    }



    func tokenField(tokenField: NSTokenField, completionsForSubstring substring: String, indexOfToken tokenIndex: Int, indexOfSelectedItem selectedIndex: UnsafeMutablePointer<Int>) -> [AnyObject]? {
        return self.completionsForSubstring(substring)
    }
}

它使用来自CoreData的PMTag实例,它们代表各个标签,因此用于标记字段中的自动完成。这应该足够接近你希望得到的东西了。