0

I'm creating a framework module using swift. Need to pop up an alert or ViewController when the button tapped. Buttons are creating programmatically. Currently button is displaying, but actions are not working. Below is the code.
In Framework class

public class CreateAdminMenu {

    let alertVC = AlertView()

    public init() {

    }

    public func createMenuItem(itemTitle: String) -> UIButton{
        let menuItem = UIButton(type: .system)
        menuItem.frame = CGRect(x: 30, y: 30, width: 150, height: 100)
        menuItem.backgroundColor = .blue
        menuItem.setTitle(itemTitle, for: .normal)
        menuItem.addTarget(self, action: #selector(menuItem_touchUpInside(sender:)), for: UIControl.Event.touchDown)
        return menuItem
    }

    @IBAction func menuItem_touchUpInside(sender: UIButton) {
        print("Menu Item tapped")
        alertVC.showAlert()
    }
}

class AlertView: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        //self.showAlert()
    }

    func showAlert() {
        let alert = UIAlertController(title: "Test Item", message: "button tapped", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))

        self.present(alert, animated: true)
    }
}

In App, ViewController

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let menu = CreateAdminMenu()
        let item = menu.createMenuItem(itemTitle: "Test Item 1")
        view.addSubview(item)
    }
}

What am I missing?

mmk
  • 182
  • 3
  • 18

1 Answers1

1

First and foremost, you should definitely not add the IBAction in framework.

Two issues

  1. You just initialize AlertView without add/embedding it in ViewController.
  2. You are presenting the UIAlertController in another view.
       public class CreateAdminMenu {

            public init() {

            }

            public func createMenuItem(itemTitle: String) -> UIButton {
                let menuItem = UIButton(type: .system)
                menuItem.frame = CGRect(x: 30, y: 30, width: 150, height: 100)
                menuItem.backgroundColor = .blue
                menuItem.setTitle(itemTitle, for: .normal)
                return menuItem
            }
        }

        class AlertView  {
            func showAlert() -> UIAlertController {
                let alert = UIAlertController(title: "Test Item", message: "button tapped", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                return alert
            }
        }


        class ViewController: UIViewController {

            override func viewDidLoad() {
                super.viewDidLoad()
                // Do any additional setup after loading the view.

                let menu = CreateAdminMenu()
                let item = menu.createMenuItem(itemTitle: "Test Item 1")
                item.addTarget(self, action: #selector(menuItem_touchUpInside(sender:)), for: UIControl.Event.touchDown)
                view.addSubview(item)
            }

            @IBAction func menuItem_touchUpInside(sender: UIButton) {
                    let alert = AlertView()
                self.present(alert.showAlert(), animated: true, completion: nil)
            }
        }

mahan
  • 12,366
  • 5
  • 48
  • 83
  • And in addition to this answer, if you want to see which button is tapped, you can set tag to each button and in menuItem_touchUpInside method you can identify the button with the tag. – Asad Ali Choudhry Mar 23 '20 at 08:28
  • @mahan; I was trying not to use UIViewController delegate in CreateAdminMenu class and want to show the VC in Framework. In your solution, IBAction moved to ViewController class which I try to move to framework class – mmk Mar 23 '20 at 08:47
  • @mahan, goal is creating a framework (like UIKit, Foundation ...etc) In the question I have mentioned. "In App" means, using created framework – mmk Mar 23 '20 at 09:01
  • @mmk You can only present `UIAlertViewController` in `AlertView ` should you embede `AlertView` in `ViewController`. Honestly, that is a very bad architecture if you do so. – mahan Mar 23 '20 at 09:15
  • @mahan; what do mean by embed AlertView? I have build the framework project and embed it to app. After that I can import that framework as "import xxxxx" – mmk Mar 23 '20 at 09:18
  • @mmb you should definitely not add `IBAction ` in framework. See this https://stackoverflow.com/questions/45118016/xcode-how-can-i-programmatically-embed-change-view-controller-within-a-contain – mahan Mar 23 '20 at 09:25
  • @mmk if you write the button action in framework but still its target can be added somewhere elsealso as you are returning the button reference from createMenuItem(itemTitle: String) method. So it may cause problems. – Najeeb ur Rehman Mar 23 '20 at 11:53
  • @mahan, @Najeeb; Thanks for your answers and advices. – mmk Mar 24 '20 at 00:48