Невозможно создать слабую ссылку на экземпляр класса NSTextView
Используя только Swift, вот мой код в AppDelegate.swift:
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var window: NSWindow
@IBOutlet var textField: NSTextView
@IBAction func displaySomeText(AnyObject) {
textField.insertText("A string...")
}
func applicationDidFinishLaunching(aNotification: NSNotification?) {
// Insert code here to initialize your application
}
func applicationWillTerminate(aNotification: NSNotification?) {
// Insert code here to tear down your application
}
}
В конструкторе интерфейсов у меня есть объект, подключенный для получения ввода от кнопки, затем вывод переходит в текстовое представление. Я пытаюсь заставить текстовое представление заполняться некоторым текстом, когда я нажимаю кнопку.
Я попробовал это с текстовым полем, но не получил ошибку, но получил звук ошибки "донг", и больше ничего не делал. В Objective-C вы должны были использовать (assign)
параметр, чтобы заставить это работать от того, что я понимаю.
Что я делаю неправильно?
6 ответов
Использование @IBOutlet var scrollView: NSScrollView
вместо @IBOutlet var textField: NSTextView
,
Затем создать свойство возвращает documentView в scrollView.
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var window: NSWindow
@IBOutlet var scrollView: NSScrollView
var textField: NSTextView {
get {
return scrollView.contentView.documentView as NSTextView
}
}
@IBAction func displaySomeText(AnyObject) {
textField.insertText("A string...")
}
func applicationDidFinishLaunching(aNotification: NSNotification?) {
// Insert code here to initialize your application
}
func applicationWillTerminate(aNotification: NSNotification?) {
// Insert code here to tear down your application
}
}
Вы не можете хранить слабую ссылку на NSTextView
из-за исторических проблем с Какао и AppKit. Подробности смотрите в документации Clang. NSTextView
помечен как NS_AUTOMATED_REFCOUNT_WEAK_UNAVAILABLE
в NSTextView.h есть также несколько других классов для поиска.
Вы пробовали использовать Swift без ссылки на ссылку вместо слабой, что похоже на назначение Objective-C (то, что вы использовали бы для NSTextView
выход в Objective-C)?
Я пытался повторить то, что вы описали. Я создал новое приложение OS X с использованием Xcode 6 beta 7. Я опустил кнопку и текстовое представление в основной форме.
Я думаю, что ваша проблема в том, что соединение с объектом Text View по какой-то причине некорректно. Чтобы упростить задачу, я соединил объекты, используя control-drag, который автоматически добавляет необходимый код. Итак, сначала я подключил текстовое представление. Для этого нажмите на объект текстового представления, пока текстовое представление не будет выбрано. Когда я делаю это в моей версии XCode, при первом нажатии на объект выбирается Bordered Scroll View. Щелкнув по нему еще раз, выберите Clip View. Наконец, щелкнув по нему еще раз, выберите Text View. Теперь я управляю перетаскиванием объекта из кода в код AppDelegate.swift (это помогает отобразить Помощник редактора, чтобы у вас был пользовательский интерфейс формы и код рядом).
Делая это, я получаю это маленькое окно:
Обратите внимание, что типом является NSTextView, а хранилище слабое. Мне осталось только добавить имя и нажать кнопку "Подключиться". Это добавляет следующий код в AppDelegate.swift:
@IBOutlet var textField: NSTextView!
Код почти такой же, как у вас, за исключением !
в конце строки, которая заставляет развернуть значение textField.
Только с этим, код, который у вас есть в вашем вопросе, должен работать.
Другая вещь, которую я бы предложил, это не использовать insertText
, Согласно документации Apple для NSTextView.insertText:
Этот метод является точкой входа для вставки текста, набранного пользователем, и, как правило, не подходит для других целей. Программную модификацию текста лучше всего выполнять, работая непосредственно с хранилищем текста.
Насколько я понимаю, под программной модификацией текста, работая непосредственно с хранилищем текста, подразумевается работа с NSText, от которого наследуется NSTextView. Поэтому вместо этого используйте NSText.string. Вот как выглядит действие кнопки нажатия в моем коде:
@IBAction func displaySomeText(sender: NSButton) {
// If you want to add a new 'A string... ' every time you click the button
textField.string! += "A string... "
// otherwise just use
//textField.string = "A string..."
}
Я добавил действие кнопки таким же образом, как я добавил текстовое представление, перетаскивая его, и в этом случае выбрав NSButton
в качестве отправителя, вместо того, чтобы оставить по умолчанию AnyObject
,
@IBOutlet автоматически делает свойство слабым IIRC, но слабое автоматически не делает свойство необязательным. Но требуется, чтобы слабое свойство было сделано необязательным, поскольку свойство можно было в любое время освободить и сделать нулевым. Поэтому вы должны объявить свои @IBOutlets как необязательные.
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var window: NSWindow? // Optional
@IBOutlet var textField: NSTextView?
@IBAction func displaySomeText(AnyObject) {
textField?.insertText("A string...") // Only call the method if the object exists
}
func applicationDidFinishLaunching(aNotification: NSNotification?) {
// Insert code here to initialize your application
}
func applicationWillTerminate(aNotification: NSNotification?) {
// Insert code here to tear down your application
}
}
Означает ли ошибка "донг" проблему цепочки респондента? Что делать, если вы позвоните becomeFirstResponder
на текстовое поле перед вставкой текста?
Чтобы создать слабую ссылку пользователя weak
ключевое слово:
пример:
@IBOutlet weak var myView: UIView
В твоем случае
@IBOutlet weak var textField: NSTextView