Я новичок в программировании и собираюсь рвать на себе волосы. У меня настроено разделенное представление (приложение macOS), и я просто пытаюсь получить метку с левой стороны, чтобы обновить текст, введенный справа, когда пользователь печатает.
Я боролся с этой проблемой около 15+ часов. Я много искал и пробовал много решений (в частности, найденных в Swift3: живое обновление UiLabel при вводе данных пользователем), ниже приведены все попытки, которые были успешно собраны, но ни один из них не меняет метку при вводе текста.
На самом деле я пытаюсь создать вид слева, похожий на заголовки с возможностью прокрутки, где он перечисляет только «заголовки», и после выбора он переносит пользователя в эту точку в тексте справа (идея состоит в том, чтобы обозначить заголовки чем-то как звездочка — поэтому он показывает только текст, строка которого начинается со звездочки) — но я понимаю, что объем этого намного больше, чем один вопрос.
Любая помощь могла бы быть полезна.
Это обычный файл Xcode с контроллером разделенного представления, одним текстовым полем и одной меткой.
примечание: заголовков «попытка» не было в коде, и каждый тестировался отдельно
class ViewController: NSViewController {
@IBOutlet weak var leftLabel: NSTextField!
@IBOutlet weak var rightText: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
...
// Attempt 1
func attempt(_ sender: NSTextField) {
leftLabel.stringValue = rightText.stringValue
}
// Attempt 2
if let textInputting = rightText {
//There is a text in your textfield so we get it and put it on the label
leftLabel.stringValue = textInputting.stringValue
} else {
//textfield is nil so we can't put it on the label
print("textfield is nil")
}
// Attempt 3
func testfunc (textField: NSTextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
leftLabel.stringValue = rightText.stringValue
return true
}
// Attempt 4
func testfunc2 (textField: NSTextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
rightText2.stringValue = rightText.stringValue
return true
}
// Attempt 5
leftLabel?.stringValue = rightText?.stringValue ?? ""
// Attempt 6
func copying (_ rightText: NSTextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
leftLabel.stringValue = rightText.stringValue
return true
}
// Attempt 7
func textField(_ textField: NSTextFieldDelegate?, shouldChangeCharactersIn range: NSRange, replacementString string: NSText) -> Bool {
leftLabel.stringValue = rightText.stringValue
return true
}
Спасибо за ответ, я очень ценю его (используя код в «попытке 7», описанный выше). Теперь я добавил NSTextFieldDelegate в «Контроллер представления классов:», но я не уверен, как реализовать уведомление об изменении текста.





На самом деле то, что вы пытаетесь сделать, не так просто. Раньше я не читал весь вопрос. Я сожалею о том, что.
Ниже приведен один из подходов с использованием NSNotification, когда приложение отправляет строку текста из одного контроллера представления с именем FirstViewController в другой с именем SecondViewController. Далее HomeViewController является подклассом NSSplitViewController, который не принимает участия в данном случае.
// HomeViewController //
import Cocoa
class HomeViewController: NSSplitViewController {
// MARK: - Variables
// MARK: - IBOutlet
// MARK: - IBAction
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
// FirstViewController //
import Cocoa
class FirstViewController: NSViewController, NSTextFieldDelegate {
// MARK: - Variables
// MARK: - IBOutlet
@IBOutlet weak var textField: NSTextField!
// MARK: - IBAction
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
textField.delegate = self
}
func controlTextDidChange(_ notification: Notification) {
if notification.object as? NSTextField == textField {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SecondViewControllerTextDidChange"), object: textField.stringValue)
}
}
}
// SecondViewController //
import Cocoa
class SecondViewController: NSViewController {
// MARK: - Variables
// MARK: - IBOutlet
@IBOutlet weak var labelField: NSTextField!
// MARK: - IBAction
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear() {
super.viewWillAppear()
NotificationCenter.default.addObserver(self, selector: #selector(passText), name: NSNotification.Name(rawValue: "SecondViewControllerTextDidChange"), object: nil)
}
override func viewWillDisappear() {
super.viewWillDisappear()
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "SecondViewControllerTextDidChange"), object: nil)
}
@objc func passText(notification: NSNotification) {
let text = notification.object as! String
labelField.stringValue = text
}
}
Таким образом, приложение передаст строку из FirstViewController в SecondViewController с помощью NSNotification. SecondViewController опубликует уведомление через свой viewWillAppear. Когда приложение покидает SecondViewController, это уведомление должно быть удалено. Важно отметить, что вам нужно выбрать каждый контроллер представления через Storyboard и установить имя класса под Identity inspector.
Дайте контроллеру представления
NSTextFieldDelegate. И используйте уведомление об изменении текста.