0

I am creating a pulldown menu using a stackview in conjunction with a textfield. When the textfield is tapped, I animate the contents of the stackview by "growing" the stackview upwards, but it is doing it from the bottom-left to the top-right corner. How can I make it "grow" straight up vertically upwards? I suspect that it may be due to the width of the buttons not being equal to the width of the stackview, but I have already set the stackview's alignment property to .fill as well as set a constraint to make the stackview's width anchor equal to the textfield's width anchor. So, I am not sure what I need to fix. Here's the code followed by a clip of how it looks right now.

import UIKit

class ViewController: UIViewController, UITextFieldDelegate {
    @IBOutlet weak var textfield: UITextField!
    @IBOutlet weak var label: UILabel!
    
    var popup: UIStackView = {
        let selectionList = ["Apple",
                             "Grapefriut",
                             "Peach",
                             "Orange",
                             "Pear ",
                            ]
        let pop = UIStackView()
        pop.axis = .vertical
        pop.spacing = 0
        pop.distribution = .fillEqually
        pop.alignment = .fill
        pop.layer.borderWidth = 1
        pop.layer.borderColor = UIColor.darkGray.cgColor
        pop.layer.cornerRadius = 6
        pop.clipsToBounds = true

        for selection in selectionList {
            let button = UIButton()
            button.setTitle(selection, for: .normal)
            button.backgroundColor = #colorLiteral(red: 0.8202667832, green: 0.9491913915, blue: 1, alpha: 1)
            button.setTitleColor(.darkGray, for: .normal)
            button.titleLabel?.font = UIFont.systemFont(ofSize: 14)
            button.addTarget(self, action: #selector(selectionTapped), for: .touchUpInside)
            button.isHidden = true
            pop.addArrangedSubview(button)
        }

        return pop
    }()
        
    override func viewDidLoad() {
        super.viewDidLoad()
        textfield.delegate = self
        
        let imageView = UIImageView(image: UIImage(named: "downarrow20x20"))
        imageView.contentMode = .center
        imageView.frame = CGRect(x: 0, y: 0, width: imageView.image!.size.width + 20.0, height: imageView.image!.size.height)
        textfield.rightView = imageView
        textfield.rightViewMode = .always
        textfield.inputView = UIView() // disable keyboard from popping up
        
        view.addSubview(popup)
        
        popup.translatesAutoresizingMaskIntoConstraints = false
        popup.bottomAnchor.constraint(equalTo: textfield.bottomAnchor).isActive = true
        popup.widthAnchor.constraint(equalTo: textfield.widthAnchor).isActive = true
        popup.centerXAnchor.constraint(equalTo: textfield.centerXAnchor).isActive = true
    }
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        showHidePopupContents(hide: false)
    }
    
    private func showHidePopupContents(hide: Bool) {
        UIView.animate(withDuration: 0.3) {
            self.popup.subviews.forEach { btn in
                btn.isHidden = hide
            }
        }
    }
    
    @objc func selectionTapped(_ button: UIButton) {
        if let buttonStr = button.title(for: .normal) {
            let str = buttonStr.trimmingCharacters(in: .whitespacesAndNewlines)
            label.text = "\(str) selected"
            textfield.text = str
        }

        // get focus out of textfield
        textfield.isEnabled = false
        textfield.isEnabled = true
        
        showHidePopupContents(hide: true)
    }
}

Pulldown stackview grows from bottom-left to top-right

Kaplan
  • 91
  • 1
  • 11
  • 1
    Have you tried constraining the button width to a constant value when you initialize them? – Jake Aug 11 '21 at 20:00
  • Yeah I just tried it: `button.frame.size.width = 124.0` Didn't help. – Kaplan Aug 11 '21 at 20:10
  • Oooh!!!! Wait, that was wrong, I now did `button.widthAnchor.constraint(equalToConstant: 124.0).isActive = true` and it works! Thanks!! – Kaplan Aug 11 '21 at 20:18
  • @Jake It works fine if I set the the widthAnchor constraint to a constant (124.0 which happens to be the width of the textfield) for each button when the `popup: UIStackView { ... }()` variable is instantiated **outside** `viewDidLoad()`. But actually I don't really know the width of the textfield at that time. I only know the width of the textfield in `viewDidLoad()`. But if I iterate through the buttons in the stackview within `viewDidLoad()` and set the widthAnchor constraint there, I get the long error message about "Unable to simultaneously satisfy constraints." – Kaplan Aug 11 '21 at 22:42
  • 1
    Are you able to make the constraint equal to the textview's width constraint? Not the same float value, but the actual width anchor? Does that help? – Jake Aug 12 '21 at 02:21
  • @Jake I couldn't make the buttons' constraint equal to the textfield's width constraint in `viewDidLoad()` because the textfield has not appeared yet at that time. I CAN do it in `viewDidAppear()`. I iterate through the stackview's subviews (the buttons) and set their widthAnchor constraint constant to the width of the textfield. But doing this alone doesn't result in the stackview growing straight up. I have to **also** set the stackview's widthAnchor to the same constant. It animates perfectly BUT, I get the notorius "Unable to simultaneously satisfy constraints" error in the debug window. – Kaplan Aug 13 '21 at 21:57
  • @Jake So, your suggestion about making the buttons inside the stackview have the same widthAnchor constraint (not float constant) as the textfield's widthAnchor constraint did the trick! However, I also have to keep the widthAnchor constraint of the stackview equal to the textfield's widthAnchor constraint, otherwise, the buttons in the stackview wouldn't "grow" vertical straight up as a block, but grows and expands from the center. So, now I have it all working and without any complaints int he debugger window about "Unable to simultaneously satisfy constraints". Thanks again. – Kaplan Aug 15 '21 at 05:18
  • Good work figuring all of that out! – Jake Aug 15 '21 at 11:59

0 Answers0