[英]Update UITextField in external view controller after a click in main view controller
I am trying to display a button on the MainViewController and a UITextField in an ExternalViewController for when the device is connected via HDMI. 我试图在通过HDMI连接设备时在MainViewController上显示一个按钮,并在ExternalViewController中显示一个UITextField。 When a click occurs in the MainViewController, I need to update the UITextField in the ExternalViewController. 当MainViewController中发生单击时,我需要更新ExternalViewController中的UITextField。 I can see the prints occur in the output window, but the text field does not update. 我可以看到打印出现在输出窗口中,但是文本字段没有更新。
MainViewController.swift MainViewController.swift
import UIKit
import WebKit
class MainViewController: UIViewController {
fileprivate var externalWindow: UIWindow?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if UIScreen.screens.count > 1 {
setupExternalScreen(UIScreen.screens[1])
}
let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
button.backgroundColor = UIColor.blue
button.setTitle("Click Me", for: UIControlState.normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.view.addSubview(button)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
fileprivate func setupExternalScreen(_ screen: UIScreen) {
guard externalWindow == nil,
let vc = self.storyboard?.instantiateViewController(withIdentifier: "ExternalScreen") as? ExternalViewController else {
return
}
externalWindow = UIWindow(frame: screen.bounds)
externalWindow!.rootViewController = vc
externalWindow!.screen = screen
externalWindow!.isHidden = false
}
func buttonAction(sender: UIButton) {
print("Button tapped")
ExternalViewController().updateLabel()
}
}
ExternalViewController.swift ExternalViewController.swift
import UIKit
class ExternalViewController: UIViewController {
let output = UITextField(frame: CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: 300, height: 100)))
override func viewDidLoad() {
super.viewDidLoad()
self.addTextField()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func addTextField() {
output.textColor = UIColor.black
output.text = "This is the other text field"
view.addSubview(output)
}
func updateLabel() {
print("inside updateLabel")
output.text = "button was clicked"
}
}
This is how it looks like. 这就是它的样子。
This is my first project with Swift, so I apologize if it is a bad question. 这是我与Swift进行的第一个项目,如果这个问题不好,我深表歉意。
Try using NotificationCentre . 尝试使用NotificationCentre。 In ExternalVC 在ExternalVC中
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(receivedDataFromNotification(notification:)), name: NSNotification.Name(rawValue: "passdata"), object: nil)
}
func receivedDataFromNotification(notification : NSNotification) -> Void {
print(notification.object);
output.text = "button was clicked"
}
In MainViewController 在MainViewController中
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "passdata"), object: "your string pass here")
While you can use a notification to transfer data between I prefer creating a delegate to transfer the data. 虽然您可以使用通知在两者之间传输数据,但我更喜欢创建一个委托来传输数据。 first create a protocol 首先创建一个协议
protocol ExternalViewControllerDelegate: class{
func shouldUpdateLabel(withText text: String)
}
Then update the ExternalViewController appropriately to contain the delegate which a weak reference of course 然后适当地更新ExternalViewController,以包含当然是弱引用的委托
class ExternalViewController: UIViewController {
weak var delegate: ExternalViewControllerDelegate?
let output = UITextField(frame: CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: 300, height: 100)))
override func viewDidLoad() {
super.viewDidLoad()
self.addTextField()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func addTextField() {
output.textColor = UIColor.black
output.text = "This is the other text field"
view.addSubview(output)
}
func updateLabel() {
print("inside updateLabel")
output.text = "button was clicked"
delegate?.shouldUpdateLabel(withText: "Your text")
}
}
Remember to call the method in the delegate. 记住要在委托中调用该方法。 I used the updateLabel method in the class to call the method. 我在类中使用了updateLabel方法来调用该方法。 Which I assume you also want to use 我认为您也想使用
Finally implement the protocol in the MainViewController and remember to set the delegate. 最后,在MainViewController中实现协议,并记住设置委托。
extension MainViewController: ExternalViewControllerDelegate{
func shouldUpdateLabel(withText text: String) {
//Do what you want with the text
}
}
Then update the setupExternalScreen method to set the delegate 然后更新setupExternalScreen方法以设置委托
func setupExternalScreen(_ screen: UIScreen) {
guard externalWindow == nil,
let vc = self.storyboard?.instantiateViewController(withIdentifier: "ExternalScreen") as? ExternalViewController else {
return
}
vc.delegate = self
externalWindow = UIWindow(frame: screen.bounds)
externalWindow!.rootViewController = vc
externalWindow!.screen = screen
externalWindow!.isHidden = false
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.