简体   繁体   中英

Swift 4 UIButton action in UIImageView not working

I am trying to add a delete button as a subview in an image. This is my current structure: -> class DesignViewController: UIViewController | -> class Sticker: UIImageView, UIGestureRecognizerDelegate | -> UI button inside the Sticker -> class DesignViewController: UIViewController | -> class Sticker: UIImageView, UIGestureRecognizerDelegate | -> UI button inside the Sticker

Inside Sticker class I have :

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let button2 = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
    button2.backgroundColor = .red
    button2.setTitle("Delete", for: .normal)
    button2.tag = 23
    button2.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)        
    self.addSubview(button2)
}

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

The buttonAction is not getting called. When I change self.addSubview(button2) line to :

self.superview?.addSubview(button2)

I can see buttonAction getting called. However I would like to keep the button inside the Sticker view so that when user moves the sticker, the button moves as a subview with it.

Can anyone please help and let me know how I can keep the button inside Sticker view?

You should create a protocol delegate for button action. This is code example:

protocol ButtonDelegate: class {
  func buttonTapped(button: UIButton)
}

class Sticker: UIImageView {

weak var delegate: ButtonDelegate?

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

    addSubview(button2)
}

lazy var button2: UIButton = {
  let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
  button2.backgroundColor = .red
  button2.setTitle("Delete", for: .normal)
  button2.tag = 23
  button2.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)        
  return button
}()

@objc func buttonAction(sender: UIButton) {
  guard let delegate = delegate else { return }
  delegate.buttonTapped(button: sender)
}

So, now go to your DesignViewControllerl, add your custom imageview class Sticker. Don't forget to do that "imageView.delegate = self". Then in extension add protocol delegate you've created before. Code example:

class DesignViewController: UIViewController {

private lazy var sticker: Sticker = {
  let iv = Sticker(frame: view.bounds)
  iv.delegate = self
  return iv
}()

  override viewDidLoad() {
    super.viewDidLoad()

    view.addSubiew(sticker)
  }

}

extension DesignViewController: ButtonDelegate {

  func buttonTapped(button: UIButton) {
    // input your action here
  }

}

By default isUserInteractionEnabled property of UIImageView is set to false. Set it to true and your button will start to respond. You can set it in code as well as in the storyboards.

Also try setting the clipsToBounds property of your imageview to true. It will clip your button if it is going outside of the image bounds. That might be one of the reason that your button is not getting touches.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM