Невозможно создать слабую ссылку на экземпляр класса 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
Другие вопросы по тегам