Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS/Swift: How to add one extension to multiple controllers?

Tags:

swift

In a file called Extensions, I'm trying to add one extension to 2 View Controllers so I don't have to write the whole code twice.

import UIKit
extension TempConvertViewController {
// code
}

I need to use the exact same code for LocationViewController.

Any help would be appreciated!

Edit: Thank you all for responding.

What I am trying to achieve is reuse the same keyboard/view code in 2 controllers as both contain textFields. The reason I've extended TempConvertViewController is because I have a variable (activeTextField) which won't be recognizable if I were to implement this in UIViewController.

If I put the code in a function, the keyboardDidShow() and keyboardWillHide() functions won't be recognized in the controller itself. I get the error: Use of unresolved identifier 'keyboardDidShow(notification:), Use of unresolved identifier 'keyboardWillHide(notification:)' See second part of the code below

Here is the extension of TempConvertViewController

extension TempConvertViewController: UITextFieldDelegate {

    @objc func keyboardDidShow(notification: Notification) {
        let notificationInfo: NSDictionary = notification.userInfo! as NSDictionary
        let keyboardSize = (notificationInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        let yKeyboard = view.frame.size.height - keyboardSize.height
        let yTextFieldEditing: CGFloat! = activeTextField?.frame.origin.y

        if view.frame.origin.y >= 0 {

            //checking if textField is covered by keyboard
            if yTextFieldEditing > yKeyboard - 60 {
                UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations:{self.view.frame = CGRect(x: 0, y: self.view.frame.origin.y -
                    (yTextFieldEditing! - (yKeyboard - 60)), width: self.view.bounds.width, height: self.view.bounds.height)}, completion: nil)
            }
        }
    }

    @objc func keyboardWillHide(notification: Notification) {
        UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: { self.view.frame = CGRect(x: 0, y:0, width: self.view.bounds.width, height: self.view.bounds.height)}, completion: nil)
    }
    func textFieldDidBeginEditing(_ textField: UITextField) {
        activeTextField = textField
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }
}

TempConvertViewController:

override func viewDidLoad() {
        super.viewDidLoad()

        // Subscribe to Notifications
        let center: NotificationCenter = NotificationCenter.default;
        center.addObserver(self, selector: #selector(keyboardDidShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        center.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

If I manage to include everything in one function, e.g. keyboardViewManagement(), can't I use a new extension for the other View Controller (LocationChangeViewController) like this:

extension LocationChangeViewController: UITextFieldDelegate {

// calling the function
func keyboardViewManagement()

}

Thank you all again!

like image 738
RochNoure Avatar asked Sep 03 '25 06:09

RochNoure


1 Answers

Use power of protocols, we are in swift after all

protocol Extendable: class {
    var editingTextField: UITextField? { get }
    func someFunc()
}

extension Extendable where Self: UIViewController {
    func someFunc() {
        // yor implementation
    }
}

class ViewController: UIViewController {
    var editingTextField: UITextField? {
        return activeTextField
    }
}
like image 137
tereks Avatar answered Sep 04 '25 21:09

tereks