问题
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