Andy Kwok
Andy Kwok

Reputation: 25

How to pass the variable from a ViewController Class to other Struct?

I have no idea how to pass the data from the class to another struct. This is my ViewController.swift file. And I have another file called Meme.swift which is used to save the struct. I tried to put the struct in ViewController.swift file as well as Meme.swift file but I cannot access the value like topTextField.text and lowTextField.text and use them in the struct. Can anyone help me with this? ViewController: import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITextFieldDelegate { @IBOutlet weak var cameraButton: UIBarButtonItem!

@IBOutlet weak var bottomTextField: UITextField!
@IBOutlet weak var topTextField: UITextField!
@IBOutlet weak var imagePickerView: UIImageView!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var actionButton: UIBarButtonItem!
let bottomTextFieldDelegate = BottomTextFieldDelegate()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    topTextField.text = "TOP"
    bottomTextField.text = "BOTTOM"
    topTextField.delegate = self
    bottomTextField.delegate = self.bottomTextFieldDelegate

}

func textFieldDidBeginEditing(_ textField: UITextField) {
    topTextField.text = ""
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    self.view.endEditing(true)
    textField.resignFirstResponder()
    actionButton.isEnabled = true
    return true
}

@IBAction func shareAction(_ sender: Any) {
    let image = generateMemedImage()
    let controller = UIActivityViewController(activityItems: [image as Any], applicationActivities: nil)
    self.present(controller, animated: true, completion: nil)
    controller.completionWithItemsHandler = {(activityType: UIActivityType?, completed:Bool, returnedItems:[Any]?, error: Error?) in

        if !completed {
            debugPrint("cancelled")
            return
        }else{
            self.save()
            self.dismiss(animated: true, completion: nil)
        }
    }
}


override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    cameraButton.isEnabled = UIImagePickerController.isSourceTypeAvailable(.camera)
    configureTextField(textField: topTextField)
    configureTextField(textField: bottomTextField)
    topTextField.textAlignment = .center
    bottomTextField.textAlignment = .center
    subscribeToKeyboardNotifications()
    actionButton.isEnabled = false

}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    unsubscribeFromKeyboardNotifications()
}

func configureTextField(textField: UITextField) {
    textField.defaultTextAttributes = memeTextAttributes
}


func save() -> Meme {
    // Create the meme
    let memedImage = generateMemedImage()
    let meme = Meme(topText: topTextField.text!, bottomText: bottomTextField.text!, originalImage: imageView.image!, memedImage: memedImage)

    return meme
}

func generateMemedImage() -> UIImage {

    // TODO: Hide toolbar and navbar
    navigationController?.setToolbarHidden(true, animated: true)
    self.navigationController?.isNavigationBarHidden = true

    // Render view to an image
    UIGraphicsBeginImageContext(self.view.frame.size)
    view.drawHierarchy(in: self.view.frame, afterScreenUpdates: true)
    let memedImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()

    // TODO: Show toolbar and navbar
    navigationController?.setToolbarHidden(false, animated: false)
    self.navigationController?.isNavigationBarHidden = false

    return memedImage
}


func keyboardWillShow(_ notification:Notification) {

    view.frame.origin.y = 0 - getKeyboardHeight(notification)
}

func keyboardWillHide(_ notification:Notification) {

    view.frame.origin.y = 0 

}

func getKeyboardHeight(_ notification:Notification) -> CGFloat { //getting the height of keyboard and use it for func keyboardWillShow to relocate
    //the keyboard using keyboardWillShow function

    let userInfo = notification.userInfo
    let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue // of CGRect
    return keyboardSize.cgRectValue.height
}

func subscribeToKeyboardNotifications() { //setting up the obeserver to be notified when keyboard is shown or not, then execute keyboardWillShow function

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: .UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: .UIKeyboardWillHide, object: nil)
}

func unsubscribeFromKeyboardNotifications() { //unsubscribe the notification

    NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
    NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
}
//setting the arributes of the text
let memeTextAttributes:[String:Any] = [
    NSStrokeColorAttributeName: UIColor.black,
    NSForegroundColorAttributeName: UIColor.white,
    NSFontAttributeName: UIFont(name: "HelveticaNeue-CondensedBlack", size: 40)!,
    NSStrokeWidthAttributeName: 3,]


@IBAction func pickAnImageFromAlbum(_ sender: Any) {
    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = .photoLibrary
    present(imagePicker, animated: true, completion: nil)
    }


@IBAction func pickAnImageFromCamera(_ sender: Any) {

    let imagePicker = UIImagePickerController()
    imagePicker.delegate = self
    imagePicker.sourceType = .camera
    present(imagePicker, animated: true, completion: nil)
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
        imagePickerView.image = image
        imagePickerView.contentMode = .scaleAspectFit
        dismiss(animated: true, completion: nil)
    }

}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController){
    dismiss(animated: true, completion: nil)
}

}

BottomFieldDelegate:

import Foundation import UIKit

class BottomTextFieldDelegate: NSObject, UITextFieldDelegate {

func textFieldDidBeginEditing(_ textField: UITextField) {
    textField.text = ""
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    let viewController = ViewController()
    textField.resignFirstResponder()
    viewController.view.endEditing(true)
    let actionButton = viewController.actionButton
    actionButton?.isEnabled = true
    return true
}

}

Upvotes: 1

Views: 963

Answers (1)

Hitesh
Hitesh

Reputation: 896

First u need to move this function like save() and generateMemedImage() into your ViewController class and then you can access topTextField.text and lowTextField.text

Modify your struct like below, and do not put nsobject in struct

struct Meme {
    var topText: String
    var bottomText: String
    var memedImage: UIImage
    var originalImage: UIImage

    init(topText: String, bottomText: String, originalImage: UIImage, memedImage: UIImage) {
        self.topText = topText
        self.bottomText = bottomText
        self.originalImage = originalImage
        self.memedImage = memedImage
    }
}

Remove save() from Meme struct and put that code in your Viewcontroller file. Modify your function which return Meme struct object.

func save() -> Meme {
        // Create the meme
        let meme = Meme(topText: topTextField.text!, bottomText: bottomTextField.text!, originalImage: imageView.image!, memedImage: memedImage)
        return meme   
}

And you can store in Array like below.

let array:[Meme] = []
array.append(save())

Upvotes: 1

Related Questions