Ярлык не будет копировать текст при наборе текста - испробовал много решений (приложение MacOS) - PullRequest
0 голосов
/ 17 марта 2019

Я новичок в программировании и собираюсь вырвать мои волосы. У меня настроено разделенное представление (приложение macOS), и я просто пытаюсь получить метку слева, чтобы обновить текст, введенный справа, когда пользователь печатает.

Я боролся с этой проблемой около 15 часов. Я много раз искал и пробовал много решений (в частности, те, которые были найдены на Swift3: обновление Live 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
        }

1 Ответ

0 голосов
/ 21 марта 2019

На самом деле то, что вы пытались сделать, не так просто.Раньше я не читал весь вопрос.Я сожалею об этом.

Ниже приведен один из подходов, использующих 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.

...