2015-11-29 8 views
1

Я новичок в Swift и прихожу из AppleScript Obj-C. Я прочитал несколько книг, и мне стало удобно с синтаксисом, но я все еще чувствую себя довольно потерянным.NSTokenField с предлагаемыми токенами с использованием Swift

Я пытаюсь создать простое поле токена, которое предлагает автозаполненные жетоны, такие как 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 
} 


} 

Итак, чтобы подвести итоги. Поскольку пользователь вводит, если первая буква «p», меню с «Помоной», «Потомак», «Питьевой», «Процесс», «Плуг» должно появиться под словом. Я не знаю, почему ничего не появляется.

Любые идеи?


EDIT:

Февраль 13 2016

Ниже ioquatix дал ответ на мой вопрос, но это за пределами моего нынешнего уровня знаний. Он указал на ключевой недостаток в моем первоначальном коде - отсутствие NSTokenFieldCellDelegate и NSTokenFieldDelegate. Благодаря его помощи мое решение (простой, но ограниченный) является:

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

Я реализовал автозавершения с использованием методов 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) 
    } 
} 

Он использует PMTag экземпляры из CoreData, которые представляют отдельные теги и поэтому используются для автоматического завершения в поле тега. Это должно быть достаточно близко к тому, что вы хотите получить что-то работающее.

+0

Благодарим вас за ответ. Я очень неопытен в кодировании любого типа, поэтому я боюсь, что ваше решение выходит за рамки моего нынешнего понимания. Тем не менее, вы указали на явный недостаток с моей первой попытки. Я не смог добавить «NSTokenFieldDelegate» и «NSTokenFieldCellDelegate». В то время я не понимал, что такое делегаты. – user3803526

+0

Вы можете в основном заменить тело функции тем, что у вас уже есть, я просто включил код из более «полного» примера. – ioquatix

+0

Да, я уверен, что ваш пример - намного лучшее решение. Я разбираюсь в том, что происходит, но я в тупике на PMTag. Это что-то в экземпляре 'NSManagedObjectContext' (' managedObjectContext')? – user3803526