0
votes

I'm following a tutorial to create an interactive popup animation (http://www.swiftkickmobile.com/building-better-app-animations-swift-uiviewpropertyanimator/), and now would like to add buttons to the popup rather than have static text as in the tutorial.

The animation works fine, but the buttons are not detecting touch. Touching the button causes the animation to reverse, instead of printing my "test" statement. From research, it looks to either be an issue with view hierarchies, the animation disabling the button touch, or layout/constraint issues with the button. I've tried addressing the above issues, but nothing has worked, was hoping someone might be able to help?

I've left out the code pertaining to the animation since I think the issue is to do with layout (and the animation seems to be working fine) - but it's still a lot; apologies in advance for the large amount of code.

class ViewController: UIViewController {

private let popupOffset: CGFloat = 440

private lazy var contentImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.image = #imageLiteral(resourceName: "Background")
    return imageView
}()

private lazy var overlayView: UIView = {
    let view = UIView()
    view.backgroundColor = .black
    view.alpha = 0
    return view
}()

private lazy var popupView: UIView = {
    let view = UIView()
    view.backgroundColor = .white
    view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
    view.layer.shadowColor = UIColor.black.cgColor
    view.layer.shadowOpacity = 0.1
    view.layer.shadowRadius = 10
    return view
}()

private lazy var closedTitleLabel: UILabel = {
    let label = UILabel()
    label.text = "Hello"
    label.font = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight.medium)
    label.textColor = UIColor.darkGray
    label.textAlignment = .center
    return label
}()

private lazy var openTitleLabel: UILabel = {
    let label = UILabel()
    label.text  = "Which door will you choose?"
    label.font = UIFont.systemFont(ofSize: 16, weight: UIFont.Weight.medium)
    label.textColor = UIColor.darkGray
    label.textAlignment = .center
    label.alpha = 0
    label.transform = CGAffineTransform(scaleX: 1.6, y: 1.6).concatenating(CGAffineTransform(translationX: 0, y: 15))
    return label
}()

private lazy var reviewsImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.image = #imageLiteral(resourceName: "LabelBackground")
    return imageView
}()

let stackView = UIStackView()
let buttonA = UIButton()
let buttonB = UIButton()
let buttonC = UIButton()

override func viewDidLoad() {
    super.viewDidLoad()
    layout()
    popupView.addGestureRecognizer(panRecognizer)
}

override var prefersStatusBarHidden: Bool {
    return true
}

//Layout

private var bottomConstraint = NSLayoutConstraint()

private func layout() {
    contentImageView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(contentImageView)
    contentImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    contentImageView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    contentImageView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    contentImageView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    overlayView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(overlayView)
    overlayView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    overlayView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    overlayView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    overlayView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    popupView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(popupView)
    popupView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    popupView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    bottomConstraint = popupView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: popupOffset)
    bottomConstraint.isActive = true
    popupView.heightAnchor.constraint(equalToConstant: 500).isActive = true

    closedTitleLabel.translatesAutoresizingMaskIntoConstraints = false
    popupView.addSubview(closedTitleLabel)
    closedTitleLabel.leadingAnchor.constraint(equalTo: popupView.leadingAnchor).isActive = true
    closedTitleLabel.trailingAnchor.constraint(equalTo: popupView.trailingAnchor).isActive = true
    closedTitleLabel.topAnchor.constraint(equalTo: popupView.topAnchor, constant: 20).isActive = true

    openTitleLabel.translatesAutoresizingMaskIntoConstraints = false
    popupView.addSubview(openTitleLabel)
    openTitleLabel.leadingAnchor.constraint(equalTo: popupView.leadingAnchor).isActive = true
    openTitleLabel.trailingAnchor.constraint(equalTo: popupView.trailingAnchor).isActive = true
    openTitleLabel.topAnchor.constraint(equalTo: popupView.topAnchor, constant: 20).isActive = true

    reviewsImageView.translatesAutoresizingMaskIntoConstraints = false
    popupView.addSubview(reviewsImageView)
    reviewsImageView.leadingAnchor.constraint(equalTo: popupView.leadingAnchor).isActive = true
    reviewsImageView.trailingAnchor.constraint(equalTo: popupView.trailingAnchor).isActive = true
    reviewsImageView.bottomAnchor.constraint(equalTo: popupView.bottomAnchor).isActive = true
    reviewsImageView.heightAnchor.constraint(equalToConstant: 428).isActive = true

    buttonA.backgroundColor = UIColor.clear
    let heightConstraintA = buttonA.heightAnchor.constraint(equalToConstant: 135)
    heightConstraintA.isActive = true
    heightConstraintA.priority = UILayoutPriority(rawValue: 999)
    buttonA.translatesAutoresizingMaskIntoConstraints = false

    buttonA.setTitle("A", for: .normal)
    buttonA.setTitleColor(UIColor.darkGray, for: .normal)
    buttonA.backgroundColor = UIColor.clear
    buttonA.addTarget(self, action: #selector(buttonATapped(sender:)), for: .touchDown)
    //self.popupView.addSubview(buttonA)

    buttonB.backgroundColor = UIColor.clear
    let heightConstraintB = buttonB.heightAnchor.constraint(equalToConstant: 135)
    heightConstraintB.isActive = true
    heightConstraintB.priority = UILayoutPriority(rawValue: 999)
    buttonB.translatesAutoresizingMaskIntoConstraints = false

    buttonB.setTitle("B", for: .normal)
    buttonB.setTitleColor(UIColor.darkGray, for: .normal)
    buttonB.backgroundColor = UIColor.clear
    //self.popupView.addSubview(buttonB)

    buttonC.backgroundColor = UIColor.clear
    let heightConstraintC = buttonC.heightAnchor.constraint(equalToConstant: 135)
    heightConstraintC.isActive = true
    heightConstraintC.priority = UILayoutPriority(rawValue: 999)
    buttonC.translatesAutoresizingMaskIntoConstraints = false

    buttonC.setTitle("C", for: .normal)
    buttonC.setTitleColor(UIColor.darkGray, for: .normal)
    buttonC.backgroundColor = UIColor.clear
    //self.popupView.addSubview(buttonC)

    popupView.addSubview(stackView)
    stackView.backgroundColor = UIColor.clear

    stackView.addArrangedSubview(buttonA)
    stackView.addArrangedSubview(buttonB)
    stackView.addArrangedSubview(buttonC)

    stackView.translatesAutoresizingMaskIntoConstraints = false
    popupView.addSubview(stackView)
    stackView.leadingAnchor.constraint(equalTo: popupView.leadingAnchor).isActive = true
    stackView.trailingAnchor.constraint(equalTo: popupView.trailingAnchor).isActive = true
    stackView.bottomAnchor.constraint(equalTo: popupView.bottomAnchor).isActive = true
    stackView.heightAnchor.constraint(equalToConstant: 428).isActive = true

    stackView.axis = .vertical
    stackView.distribution = .fill
    stackView.translatesAutoresizingMaskIntoConstraints = false

}

@objc func buttonATapped(sender: UIButton) {
    print ("test")
}



private func animateTransitionIfNeeded(to state: State, duration: TimeInterval) {
    //Animation code
}

@objc private func popupViewPanned(recognizer: UIPanGestureRecognizer) {
    //Animation code
}
}

***For anyone else having the same issue, here is how I solved it, thanks to @OverD: I removed the reviewsImageView completely (because that was only for color in my case, and I can easily add the color to the UIButton instead) Then instead of adding the buttons to the popupView, I added them to the stack view, and the stack view to the popupView. Lastly, my syntax for addTarget was not correct, and for some reason changing it to touchDown instead of touchUpInside made it work.

1
From your code here I can see your adding the buttons twice. Once as a subview if the popView and once to the stackView and then you are adding the stack view tithe populview. And your are not assigning the button any targetsOverD
@OverD thank you so much for your help!! You're totally right in that I still had my addTarget line commented out (oops), but the main help was that I hadn't even noticed I was adding the button multiple times as subviews. If you don't mind writing your comments as an answer instead of a comment, I can accept it! Thanks again! :-)LSteele
Glad I could helpOverD

1 Answers

0
votes

I noticed from the provided code that you are adding the same buttons multiple times, once as a subview of the popView and once in the stackView. Also you are not assigning any targets for the buttons.

I hope this helps