Reputation: 41
There are some similar questions out there on this, but they're in Obj-C and don't specifically answer my question.
I'm building a Tinder-like dating application with a button on the card that allows the current user to view more info about the user on the displayed card. I've written this button (moreInfoButton) programmatically and have it displayed on the card (UIView) without a problem. But when I click on the button, it does not function. I've tried isEnabled and isUserInteractionEnabled, but neither work. Here's my code:
import UIKit
import SDWebImage
class CardView: UIView {
var imageView = UIImageView(image: #imageLiteral(resourceName: "lady5c"))
var informationLabel = UILabel()
var images: [String]?
var userId: String?
var stackView: UIStackView?
let moreInfoButton: UIButton = {
let button = UIButton(type: .system)
button.setImage(#imageLiteral(resourceName: "info_icon").withRenderingMode(.alwaysOriginal), for: .normal)
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
layer.cornerRadius = 15
clipsToBounds = true
imageView.contentMode = .scaleAspectFill
addSubview(imageView)
imageView.fillSuperview()
addSubview(informationLabel)
informationLabel.numberOfLines = 0
informationLabel.anchor(top: nil, leading: leadingAnchor, bottom: bottomAnchor, trailing: trailingAnchor, padding: .init(top: 0, left: 16, bottom: 16, right: 16))
informationLabel.text = ""
informationLabel.textColor = .white
informationLabel.layer.zPosition = 1
addSubview(moreInfoButton)
moreInfoButton.anchor(top: nil, leading: nil, bottom: bottomAnchor, trailing: trailingAnchor, padding: .init(top: 0, left: 0, bottom: 20, right: 20), size: .init(width: 50, height: 50))
moreInfoButton.layer.zPosition = 1
moreInfoButton.isUserInteractionEnabled = true
// let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
// addGestureRecognizer(panGesture)
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
}
Upvotes: 0
Views: 1196
Reputation: 1630
UPDATE: Since the button is sitting on top of the tappable view, make sure the button is displayed in front of the tappable view. If you are using storyboard, the button should be listed below the tappable view.
Also, in your touchesBegan method, make sure you don't respond to touches inside your button:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if touch?.view != button && touch?.view == tappableView {
// Next picture
}
}
If that still doesn't work, try this implementation of touchesBegan instead:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if touch?.view == button {
// performSegue or call button's target function
} else if touch?.view == tappableView {
// Next picture
}
}
You are missing a target for your button:
moreInfoButton.addTarget(self, action: #selector(buttonTapped(_:)), forControlEvents: .TouchUpInside)
and a function to handle the tap:
@objc func buttonTapped(sender: UIButton!) {
// action
}
Upvotes: 0
Reputation: 303
if you add a button programmatically, I think you should use addTarget instead of using whole uiview gesture. This makes button has a functionality without having any relation about view gestures.
lazy var button: UIButton = {
let temp = UIButton(type: .system)
temp.isUserInteractionEnabled = true
temp.addTarget(self, action: someFunction, for: UIControl.Event.touchUpInside)
return temp
}()
Upvotes: 1
Reputation: 3802
Disable cancelsTouchesInView
property of the gesture. By default, I think it is set to true
. This means that the gesture consumes the touch event and it is not passed on to the button
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
tapGesture.cancelsTouchesInView = false
addGestureRecognizer(tapGesture)
Upvotes: 0
Reputation: 1739
I think UITapGestureRecognizer conflict with button tap event. You can try use override touchesBegan event instead of tap gesture.
Upvotes: 0