Label won't copy Text as typing - tried many solutions (MacOS app)

核能气质少年 提交于 2020-05-28 11:51:47

问题


I'm new to coding and about to tear my hair out. I have a split view set up (macOS app) and I'm just trying to get a label on the left hand side to update to text entered on the right as the user is typing.

I’ve been struggling for around 15+ hours with this problem. I’ve searched extensively and tried many solutions (notably those found at Swift3: Live UiLabel update on user input), below are all the attempts that have build successfully but none change the label when entering text.

I’m actually trying to create a scoll-able headings-like view on the left where it only lists ‘headings’ and upon selection it takes the user to that point in the text on the right (the idea is to denote headings with something like an asterisk - so it only shows text whose line begins with an asterisk) — but I understand the scope of that is much larger than one question.

Any help would be really appreciated.

It's just a normal Xcode file with a split view controller, one text field and one label.

note: the 'attempt' titles were not in the code and each was tested separately

    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:


Actually, what you have been trying to do is not that simple. Previously, I did not read the entire question. I'm sorry about that.

The following is one approach using NSNotification where the application will send a string of text from one view controller named FirstViewController to another named SecondViewController. In the following, HomeViewController is a subclass of NSSplitViewController which takes no part in this case.

// 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
    }
}

In summary, the application will pass the string from FirstViewController to SecondViewController with NSNotification. SecondViewController will post a notification through its viewWillAppear. When the application leaves SecondViewController, this notification must be removed. It is important to note that you need to select each view controller through Storyboard and set the class name under the Identity inspector.



来源:https://stackoverflow.com/questions/55202604/label-wont-copy-text-as-typing-tried-many-solutions-macos-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!