Пользовательский UIView: UIButton addTarget не вызывается

Моя проблема в том, что у меня есть пользовательский UIView, который представляет всплывающее окно. Внутри этого представления я хочу иметь ползунок, метка которого обновляется каждый раз, когда я перетаскиваю ползунок. Логика слайдера работает, по крайней мере, когда я использую ее непосредственно в ViewController, но не с моим пользовательским представлением. В частности, метод, указанный в addTarget, вообще не вызывается. Я также попытался установить backgroundColor ползунка к чему-то, и он действительно обнаружился, что означает, что у него есть рамка. Итак, что мне здесь не хватает? У меня была подобная проблема много раз с UIButton и т. Д. В пользовательских подклассах UIView.

class PriceVoteController: UIView {

var parentView: UIView = UIView()

let slider: UISlider = {
    let slider = UISlider()
    slider.isContinuous = true
    slider.minimumValue = 1
    slider.maximumValue = 3
    slider.setMinimumTrackImage(#imageLiteral(resourceName: "minimumSliderTrackImage").resizableImage(withCapInsets: UIEdgeInsets(top: 0, left: 9, bottom: 0, right: 9)), for: .normal)
    slider.setMaximumTrackImage(#imageLiteral(resourceName: "maximumSliderTrackImage").resizableImage(withCapInsets: UIEdgeInsets(top: 0, left: 9, bottom: 0, right: 9)), for: .normal)

    let sliderThumb = #imageLiteral(resourceName: "sliderThumImage")
    slider.setThumbImage(sliderThumb, for: .normal)

    slider.addTarget(self, action: #selector(adjustPriceLabel), for: .valueChanged)

    slider.setValue(2.0, animated: true)

    return slider
}()

let priceLabel: UILabel = {
    let label = UILabel()
    label.textAlignment = .center
    return label
}()

let blackView: UIView = {
    let view = UIView()
    view.backgroundColor = .black
    view.alpha = 0.2
    return view
}()

let popUpView: UIView = {
    let view = UIView()
    view.layer.backgroundColor = UIColor.white.cgColor
    view.layer.cornerRadius = 10
    return view
}()

@objc fileprivate func adjustPriceLabel() {
    print("adjust label")
    priceLabel.text = String(format: "%.1f", slider.value)
    priceLabelLeftConstraint.constant = getXPositionForSliderValue()
}

fileprivate func getXPositionForSliderValue() -> CGFloat {
    guard let currentThumbImage = slider.currentThumbImage else { return 0 }
    let sliderRange = slider.frame.size.width - currentThumbImage.size.width;
    let sliderOrigin = slider.frame.origin.x + (currentThumbImage.size.width / 2.0);

    let sliderValueToPixels = ((CGFloat(slider.value - slider.minimumValue)/CGFloat(slider.maximumValue - slider.minimumValue)) * sliderRange) + sliderOrigin;

    return sliderValueToPixels;
}

var priceLabelLeftConstraint: NSLayoutConstraint = NSLayoutConstraint()

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

    self.isUserInteractionEnabled = true
}

fileprivate func setupSlider() {
    self.popUpView.addSubview(slider)
    slider.anchor(top: self.popUpView.topAnchor, left: self.popUpView.leftAnchor, bottom: nil, right: self.popUpView.rightAnchor, paddingTop: 10, paddingLeft: 50, paddingBottom: 0, paddingRight: 50, width: 0, height: 0)

    self.popUpView.addSubview(priceLabel)
    priceLabel.text = String(slider.value)

    priceLabel.anchor(top: slider.bottomAnchor, left: nil, bottom: nil, right: nil, paddingTop: 10, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
    priceLabelLeftConstraint = priceLabel.centerXAnchor.constraint(equalTo: self.popUpView.leftAnchor, constant: getXPositionForSliderValue())
    priceLabelLeftConstraint.isActive = true
}

func showOn(view: UIView) {
    parentView = view

    parentView.addSubview(self.popUpView)

    self.popUpView.anchor(top: nil, left: nil, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width - 100, height: 200)
    self.popUpView.centerXAnchor.constraint(equalTo: parentView.centerXAnchor).isActive = true
    self.popUpView.centerYAnchor.constraint(equalTo: parentView.centerYAnchor).isActive = true

    setupSlider()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
}

Я действительно надеюсь, что кто-то может помочь мне с этим, поскольку я пытался выяснить это в течение последних часов... и никакого решения:/ Как я уже сказал, метод вызывается, когда все находится внутри ViewController и его представления, но не с пользовательским UIView.

И, кстати, свойство parentView является основным представлением viewController, где инициализируется пользовательский UIView. Я инициализирую его пустым конструктором, а затем вызываю show() с представлением ViewController.

Спасибо за вашу помощь! Роберт

1 ответ

Итак, наконец-то я нашел решение... Для всех, кто сталкивается с одной и той же проблемой: посмотрите на вашу иерархию представлений. Мне не хватало связи между моим popUpView и моим customView, поэтому сенсорные события не запускались должным образом. Другая ошибка заключалась в том, что всплывающее окно никогда не привязывалось должным образом и не имело собственного фрейма... Вот почему слайдер вообще не работал. Я надеюсь, что это поможет некоторым из вас, ребята!

Другие вопросы по тегам