0
masterBtn.addTarget(self, action: #selector(self.masterBed), for: UIControlEvents.touchUpInside)

i have used above code in subview but it doesn't fire function masterBed. the button within subview is not clickable

Full code:

let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
button.setTitleColor(.gray, for: .normal)
button.center = CGPoint(x: 380, y: 110)
button.setTitle(">", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.addSubview(button)

func buttonAction () {
    print("button pressed")
}
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
Rushikesh Welkar
  • 143
  • 1
  • 2
  • 8
  • Did you set `isUserInteractionEnabled = true` for the button or did you enable it in Storyboard? – Dávid Pásztor Aug 28 '17 at 12:00
  • 2
    Can you provide more details? As is your question is not very useful. – Lorenzo B Aug 28 '17 at 12:03
  • i have write this code in subview and call buttonAction function but nothing print in console. and actually i am not using storyboard. let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50)) button.setTitleColor(.gray, for: .normal) button.center = CGPoint(x: 380, y: 110) button.setTitle(">", for: .normal) button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside) self.addSubview(button) – Rushikesh Welkar Aug 28 '17 at 12:07
  • func buttonAction () { print("button pressed") } – Rushikesh Welkar Aug 28 '17 at 12:07
  • @RushikeshWelkar in the future please edit your original question with properly formatted code, instead of posting it as a comment. I have included your comment in the question for now. And you should try enabling user interaction as I explained in my first comment. – Dávid Pásztor Aug 28 '17 at 12:22
  • ok ..thanks@DávidPásztor – Rushikesh Welkar Aug 28 '17 at 12:25
  • you have defined buttonAction instead of masterBed method on button click, so it'll not invoke the masterBed method. – Rahul Kumar Aug 28 '17 at 12:27
  • both are used for different buttons please consider buttonAction code @RahulKumar – Rushikesh Welkar Aug 28 '17 at 12:29

5 Answers5

5

I believe the height and width of the subview remains 0 because the button is not bound to any edges and the button seem to define the height of its superview. You could always check this by settings clipToBounds = true. Its always good to call the lazy if you are using self within an view.

This should solve your problem:

class buttonView: UIView {
private lazy var button: UIButton = {
    let button = UIButton()
    button.setTitleColor(.gray, for: .normal)
    button.setTitle("MyButton", for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
    return button
}()

override init(frame: CGRect) {
    super.init(frame: frame)
    setup()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setup()
}

func setup() {
    addSubview(button)

    addConstraint(NSLayoutConstraint(item: button, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 10))
    addConstraint(NSLayoutConstraint(item: button, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1, constant: 10))
    addConstraint(NSLayoutConstraint(item: button, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0))
    addConstraint(NSLayoutConstraint(item: button, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1, constant: 0))
    addConstraint(NSLayoutConstraint(item: button, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 80))
    addConstraint(NSLayoutConstraint(item: button, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 35))
}

func buttonAction() {
    //Do stuff
    }
}

Slightly unsure about the NSLayoutConstraints, since i use SnapKit or anchorpoints. But i think this should be correct.

Vollan
  • 1,887
  • 11
  • 26
2

I have same problem. To solve it just set isUserInteractionEnabled = true to PARENT view (view were you add button subview)

Dmih
  • 530
  • 6
  • 9
1

inside on the Masterbed property, put userinteractionenbaled = true, that will fix the problem, other stuff is the addSubview... put that on the subView Item or Class.. like masterBed.addSubView(youurButton) and if you use userinteration on the button.. really has no sense because the button is already an object created for interacions.. it's the same thing if we put a button on UIImageView, we need activated on the property on the UIImageView, to interact with the button. like this Sample..

  class ViewController: UIViewController {

 let myImage: UIImageView = {
    let image = UIImageView()
    image.backgroundColor = UIColor.brown
    image.translatesAutoresizingMaskIntoConstraints = false
    image.isUserInteractionEnabled = true    // here activate the interaction needed
    image.image = UIImage(imageLiteralResourceName: "backgroundSE.jpg")
    return image
}()

let textLabel: UILabel = {
   let label = UILabel()
    label.text = "My App"
    label.textColor = UIColor.white
    label.font = UIFont.boldSystemFont(ofSize: 25)
    label.textAlignment = .center
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

lazy var sendMailButton: UIButton = {
    let button = UIButton(type: .system)
    button.setTitle("Send Mail", for: .normal)
    button.setTitleColor(.white, for: .normal)
    button.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.layer.cornerRadius = 14
    button.addTarget(self, action: #selector(handleSendMail), for: .touchUpInside)
    return button
}()

override func viewDidLoad() {
    super.viewDidLoad()


    view.addSubview(myImage)
    myImage.addSubview(sendMailButton)
    myImage.addSubview(textLabel)

    setupLayouts()

}

@objc func handleSendMail() {
    print("Mail Sended")
}

I hope this help you and fix the problem, cheers!

0

I have edited your code as below, it's working.

Your ViewController Class

class ViewController: UIViewController, HomeViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        middleView()
    }

    func middleView() {
        let customView = HomeView(frame: CGRect(x: 60, y: 100, width: 250, height: 100))
        self.view.addSubview(customView)
        customView.backgroundColor = UIColor.green
        customView.delegate = self
    }

    func buttonAclicked(_ sender: UIButton) {
        print("button click action in viewController")
    }

}

HomeView Class

import UIKit

protocol HomeViewDelegate {

    func buttonAclicked(_ sender: UIButton)
}

class HomeView: UIView {

    var delegate:HomeViewDelegate?

    override init(frame: CGRect) {
        super.init(frame: frame)
        initView()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func initView() {
        let button = UIButton(frame: CGRect(x: 10, y: 10, width: 80, height: 35))
        self.addSubview(button)
        button.setTitleColor(.gray, for: .normal)
        button.setTitle("MyButton", for: .normal)
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
    }

    func buttonAction(_ sender: UIButton) {
        print("button pressed")
        delegate?.buttonAclicked(sender)
    }

}
Rahul Kumar
  • 3,009
  • 2
  • 16
  • 22
0

might be your subview is out off parent view frame so can you try to give same frame as parent view frame and try like this:

let button = UIButton(frame: self.frame)//Parent view frame
button.setTitleColor(.gray, for: .normal)
//button.center = CGPoint(x: 380, y: 110) // comment this line 
button.setTitle(">", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
self.addSubview(button)