简体   繁体   中英

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. When a click occurs in the MainViewController, I need to update the UITextField in the ExternalViewController. I can see the prints occur in the output window, but the text field does not update.

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

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.

Try using NotificationCentre . In 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

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

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. Which I assume you also want to use

Finally implement the protocol in the MainViewController and remember to set the delegate.

extension MainViewController: ExternalViewControllerDelegate{
    func shouldUpdateLabel(withText text: String) {
        //Do what you want with the text
    }
}

Then update the setupExternalScreen method to set the delegate

 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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM