Can not set the value in the label using delegate protocol - ios

enter image description herei am making a program with delegate protocol in which we add value in text field in second controller and click save and this value is set to the label in the previous viewController
all the this are done but the value can not set to the label
Can someone please explain me what is triggering the messageData() method in the main ViewController?
import UIKit
protocol SenderViewControllerDelegate {
func messageData(data: String)
}
class NewViewController: UIViewController {
//MARK:- Properties
#IBOutlet weak var firstTextField: UITextField!
var delegate: SenderViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func SaveFirstValue(_ sender: Any) {
if delegate != nil{
if firstTextField.text != nil{
let data = firstTextField.text
delegate?.messageData(data: data!)
dismiss(animated: true, completion: nil)
}
}
}
}
import UIKit
class ViewController: UIViewController,SenderViewControllerDelegate {
//MARK:- Properties
#IBOutlet var firstLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//MARK:- Actions
func messageData(data: String) {
firstLabel.text = data
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSendingVc" {
let viewController : ViewController = segue.destination as! NewViewController
ViewController.delegate = self
}
}
}

Change this line
let viewController = segue.destination as! NewViewController
viewController.delegate = self

`ViewController.delegate = self` should be `viewController.delegate = self`
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSendingVc" {
let viewController : NewViewController = segue.destination as! NewViewController //destination is type NewViewController not ViewController
// ViewController.delegate = self //Wrong
viewController.delegate = self
}
}

You made mistake in the line ViewController.delegate = self it should be
viewController.delegate = self
means small "v" (object of ViewController)
UPDATED:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showSendingVc" {
let objectOfVC = segue.destination as! NewViewController
objectOfVC.delegate = self
}
}

In ViewController Class set the delegate inside ViewDidLoad method like this:
newViewControllerObj. delegate = self
Without calling viewController Class, the delegate will not set So you have to call ViewController class inside NewViewController or other class which will call first like that:
let ViewControllerObj = ViewController()

Related

I'm trying to use a protocol and delegate pattern which will pass the data in my array back to the parent view controller

I am new to Xcode and am trying to save an array from secondViewController into the View controller. I have a a series of view controllers embedded in a navigation controller so when I click 'back' on the navigation bar I want to keep the data that was collected in an array 'collectionArray' and save to 'collectionArray2' . Here is the protocol delegate method I've tried:
This is in my ViewController where I want the array saved to :
import UIKit
class ViewController: UIViewController {
var collectionArray2: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
let controller = secondViewController()
controller.delegate = self
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let first = segue.destination as! secondViewController
first.collectionArray.append(contentsOf: collectionArray2)
}
}
extension ViewController: PopupDelegate {
func popupSelectedView(array: [String]) {
collectionArray2.append(contentsOf: array)
}
}
This is my secondViewController where I want to take 'collectionArray':
import UIKit
protocol PopupDelegate: class{
func popupSelectedView(array: [String])
}
class secondViewController: UIViewController {
var exerciseButton: String!
var collectionArray: [String] = []
weak var delegate: PopupDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func Exercisess(_ sender: UIButton){
exerciseButton = sender.currentTitle
collectionArray.append(exerciseButton!)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if self.isMovingFromParent {
delegate?.popupSelectedView(array: collectionArray)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let second = segue.destination as! FinalViewController
second.cellLabelArray.append(contentsOf: collectionArray)
}
}
Thank you
your problem is that your are referring to a difference instance of secondViewController. Don't set your delegate in viewDidLoad but when you prepare the segue:
override func viewDidLoad() {
super.viewDidLoad()
//let controller = secondViewController() REMOVE THIS
//controller.delegate = self REMOVE THIS
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let first = segue.destination as! secondViewController
first.collectionArray.append(contentsOf: collectionArray2)
first.delegate = self // set the delate here
}
}
by the way, you should name all your classes starting with capital letters, so it should be SecondViewController

Delegate method is not called swift ios?

We have two controller - ControllerA and ControllerB. Controller A contains the normal button and text field(mail id). When we enter the mailid and tap the button. we will present the ViewControllerB and we have an option called to change the email and click back. We are using a delegate to pass the viewControllerB value to ViewController. But delegate function is not called.
ViewControllerB :
protocol countryViewControllerDelegate{
func passMailId(code: String)
}
var delegate: countryControllerDelegate?
#IBAction func createNewFolder(_ sender: Any?) {
delegate?.countryCode(code: emailText.text)
self.dismiss(animated: true, completion: nil)
}
ViewControllerA :
var instance = ViewControllerB()
override func viewDidLoad() {
instance.delegate = self
}
func showCoutryPicker(){
self.performSegue(withIdentifier: "DropDown", sender: self)
}
extension ViewControllerA:countryViewControllerDelegate{
func countryCode(code: String) {
print(code)
}
}
Is any other way to fix this?
Your segue instance is different than the 1 here
var instance = ViewControllerB()
So you should either present
self.present(instance,animated:true,completion:nil)
OR
inside prepareForSegue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "DropDown" {
let des = segue.destination as! ViewControllerB
des.delegate = self
}
}
Simply use prepare(for segue: ) check the code below,
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "DropDown"){
let vc = segue.destination as! ViewControllerB
vc.delegate = self
}
}
The problem you had is that you are creating an instance from ViewControllerB
var instance = ViewControllerB()
And segue on the other hand, it wont work because it would be considered as a new instance rather than the segue destination.
You can use either delegate or instance in the below code. It will be useful for anyone:
ViewController :
class ViewController: UIViewController {
#IBOutlet weak var myTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
myTextField.text = "Hello World"
// Do any additional setup after loading the view, typically from a nib.
}
// Without segue
#IBAction func passData(_ sender: Any) {
let sb = storyboard?.instantiateViewController(withIdentifier: "viewcontroller2") as! ViewController2
sb.passText = "Hello World"
//set self to Delegate
sb.delegate = self
//set self to Instance
sb.instance = self
present(sb, animated: true, completion: nil)
}
// With segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let sb = segue.destination as! ViewController2
sb.passTextSegue = "Hello World with segue"
//set self to Delegate
sb.delegate = self
//set self to Instance
sb.instance = self
}
}
extension ViewController : ViewController2Delegate{
func passValue(Str: String) {
print(Str)
}
}
ViewController2 :
protocol ViewController2Delegate : class {
func passValue(Str:String)
}
class ViewController2: UIViewController {
//Create instance for Delegate
weak var delegate : ViewController2Delegate?
//Create instance for ViewController
var instance: ViewController?
override func viewDidLoad() {
super.viewDidLoad()
myTextField.text = passText
myTextFieldSegue.text = passTextSegue
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var myTextField: UITextField!
var passText: String?
#IBOutlet weak var myTextFieldSegue: UITextField!
var passTextSegue: String?
#IBAction func manage(_ sender: UIButton) {
//Pass value using Delegate
delegate?.passValue(Str: "Happy Coding~")
//Pass value using Instance
instance?.myTextField.text = "Happy Coding~ :)"
dismiss(animated: true, completion: nil)
}
/*
// 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.
}
*/
}

Custom protocol delegate method not calling

I am trying to change lable of one view controller from another view controller using custom protocol but its delegate method is not being called
ViewController3 code:
when i click on close button it's delegate method is not being called in my ViewController2.
protocol ViewController3Delegate: class {
func changeLable(_ text: String)
}
class ViewController3: UIViewController {
weak var delegate: ViewController3Delegate?
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func btnCloseAction(_ sender: Any) {
delegate?.changeLable("fillter applied")
self.dismiss(animated: true, completion: nil)
}
}
ViewController2 code:
class ViewController2: UIViewController,ViewController3Delegate {
#IBOutlet weak var lblReport: UILabel!
let VC3 = ViewController3(nibName: "ViewController3", bundle: nil)
override func viewDidLoad() {
super.viewDidLoad()
VC3.delegate = self
}
func changeLable(_ text: String) {
print("delegate called")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Anybody knows where i am wrong, please suggest me some solution
You have not defined a delegate in your ViewController2 which will be used to the delegate in ViewController3 .
See This :
protocol ViewController3Delegate: class {
func changeLable(_ text: String)
}
class ViewController3: UIViewController {
weak var delegate: ViewController3Delegate?
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func btnCloseAction(_ sender: Any) {
if delgate !=nil {
delegate?.changeLable("fillter applied")
self.dismiss(animated: true, completion: nil)
}
}
}
And then in your ViewController2 class :
class ViewController2: UIViewController,ViewController3Delegate {
#IBOutlet weak var lblReport: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
func changeLable(_ text: String) {
print("delegate called")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier = "Yoursegueientifier"
{
let vc = segue.destination as! ViewController3
vc.delegate = self
}
}
}
Note : You have to define your segueidentifer name in your storyboard
You should first present ViewController3 from ViewController2 like this:
let VC3 = ViewController3(nibName: "ViewController3", bundle: nil)
VC3.delegate = self
self.presentViewController(VC3, animated: true, completion: nil)
Also, you can delete this line above viewDidLoad
let VC3 = ViewController3(nibName: "ViewController3", bundle: nil)

How can I run delegated method inside IBAction?

I have some methods in second view controller. I access them through delegate - inside func buttonSender. Main goal is to pass currentTitle of a button as an argument to a viewController.addNewMessage. What is the best way to do this?
ChatViewController:
protocol ReactToButtons {
func buttonSender(viewController: MyChatViewController)
}
class MyChatViewController: ChatViewController{
var delegate: ReactToButtons?
override func viewDidLoad() {
super.viewDidLoad()
delegate!.buttonSender(self)
}
}
ContainerViewController:
class ContainerViewController: UIViewController, ReactToButtons {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let myVC = segue.destinationViewController as! MyChatViewController
myVC.delegate = self
}
func buttonSender(viewController: MyChatViewController) {
viewController.addNewMessage(/*HERE GOES CURRENT TITLE*/)
}
#IBAction func leftButtonPressed(sender: AnyObject) {
let currentTitle = sender.currentTitle!
}
I have change my answer to suit your code
class ContainerViewController: UIViewController, ReactToButtons {
var delegate: MyChatViewController!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let myVC = segue.destinationViewController as! MyChatViewController
myVC.delegate = self
}
func buttonSender(viewController: MyChatViewController) {
delegate = viewController
}
#IBAction func leftButtonPressed(sender: AnyObject) {
let currentTitle = sender.currentTitle!
delegate!.addNewMessage(currentTitle)
}
}

Save variables between View Controllers using a segue

I use Swift and Xcode 6.4 and I would like to pass a variable from one View Controller to another using a Segue.
When you press the button, the variable duration should give the value to the ViewController2. In the ViewController2 I want to use this variable again.
Main.storyboard button identifier called Test1
How can I do that? Can you help me with my code? Whats wrong?
Thanks
Code ViewController1:
import UIKit
class ViewController1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func ButtonTapped(sender: AnyObject) {
var duration = 1.0
self.performSegueWithIdentifier("Test1", sender: duration)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier = "Test1") {
let secondViewController = segue.destinationViewController as ViewController2
let duration = sender as Double
secondViewController.duration = duration
}
}
}
Code ViewController2:
import UIKit
class ViewController2: UIViewController {
var duration:Double?
var result = duration + 2.0
println(\(result))
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
var duration = Double() // now "duration" is global
#IBAction func ButtonTapped(sender: AnyObject) {
duration = 1.0
self.performSegueWithIdentifier("Test1", sender: duration)
// VVV Any new variable created in this scope will be deallocated
} // HERE
//Then this scope starts...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "Test1") {
let secondViewController = segue.destinationViewController as ViewController2
// delete this... duration = sender as Double
secondViewController.duration = duration
}
}

Resources