1

I am new to swift and trying to create a UIButton programmatically. I have two classes. I am creating a button in one class and calling that method from another class.

class viewcontroller

import UIKit

class ViewController: UIViewController {
  override func viewDidLoad() {
    super.viewDidLoad()

    let renderobj = render()
    renderobj.sign()
}
  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
  }
}

class render

import UIKit

class render: UIViewController {
  func sign() {
    let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
    button.backgroundColor = .green
    button.setTitle("Test Button", for: .normal)
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)

    self.view.addSubview(button)
  }

  func buttonAction(sender: UIButton!) {
    print("Button tapped")
  }
}

But no button is created. If I put the UIButton code inside viewDidLoad() , it works. I want the button to be created in a function of different class. Is it possible to do so ?

Thanks for any help

1
  • You are creating a new instance of render class in your viewDidLoad. You should use the one which is already added to your view hierarchy. Commented Jan 4, 2017 at 13:55

4 Answers 4

1
func sign() -> UIButton
{
   let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
   button.backgroundColor = .green
   button.setTitle("Test Button", for: .normal)
   button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
   return button 
}

After returning that button you can add it in your calling view controller view

override func viewDidLoad() {
super.viewDidLoad()

let renderobj = render()
let button = renderobj.sign()
self.view.addSubview(button)
}
Sign up to request clarification or add additional context in comments.

Comments

1

After doing this

let renderobj = render()

And after calling this function, a new button is initialized and added to the view of render view controller.

renderobj.sign()

But renver view controller is only initialized and its view is not added to current view controller which is ViewController

If you want to show render controller, then present it like usual. If you want to add that button to your ViewController then either declare a button variable and access it or return it in sign() function

Comments

1

I think there is a lack of understanding around the concepts of a UIViewController here. A UIViewController is used to manage the views displayed to a user, think about it as a single screen of your app. You can embed view controllers in other view controllers, but typically you won't need to do this for basic stuff.

A UIViewController has a lifecycle which you can find more about here: https://developer.apple.com/reference/uikit/uiviewcontroller#1652793

Now what it appears like you want to do is to wrap up the functionality of creating a button, you can do this by either creating a factory method in you ViewController class (or other class somewhere else), or by subclassing UIButton and creating a convenience initialiser method to create the button with the properties you want (you can also use Swift extensions but I won't go into that here).

Lets look at the simplest method and create a factory method inside your ViewController class:

// The button method takes a title and a selector (the selector is the method that should be called when the button is tapped)
func makeButton(title: String, action: Selector) -> UIButton {

    // Create a basic button with a default size
    let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))

    // Customise the button with your settings
    button.backgroundColor = .green
    button.setTitle(title, for: .normal)
    button.addTarget(self, action: action, for: .touchUpInside)

    // Return the newly created button
    return button
}

Now we have a method that creates a button of a default size and position, we want to call that method to create a button and then add it as a subview of the ViewController's view. To do that we can do something in the viewDidLoad() method that we override:

override func viewDidLoad() {

    // Always remember to call the super method to ensure all super classes have a chance to do any work thats required by them
    super.viewDidLoad()

    // Create the button by calling our new method
    let button = self.makeButton(title: "Test Button", action: #selector(buttonTapped))

    // Set the origin of the button to move it to the right position
    button.frame.origin = CGPoint(x: 100, y: 100)

    // Finally add the new button as a subclass of the view controllers view
    self.view.addSubview(button)
}

Now we understand whats going on in the methods we can put it all together to have a class that looks like this:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {

        super.viewDidLoad()

        let button = self.makeButton(title: "Test Button", action: #selector(buttonTapped))
        button.frame.origin = CGPoint(x: 100, y: 100)
        self.view.addSubview(button)
    }

    func makeButton(title: String, action: Selector) -> UIButton {

        let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))

        button.backgroundColor = .green
        button.setTitle(title, for: .normal)
        button.addTarget(self, action: action, for: .touchUpInside)

        return button
    }

    func buttonTapped(sender: UIButton) {

        print("Button tapped")
    }
}

Comments

0

You create new UIViewController here:

let renderobj = render()
renderobj.sign()

but ViewController instance is showing in this moment.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.