简体   繁体   English

自定义UIView:未调用UIButton addTarget

[英]Custom UIView: UIButton addTarget not called

My problem is that I have a custom UIView, which is representing a popup. 我的问题是我有一个自定义UIView,它代表一个弹出窗口。 Inside this view I want to have a slider, which has a label that gets updated every time I drag the slider around. 在此视图内,我希望有一个滑块,该滑块的标签每次我拖动滑块时都会更新。 The slider logic works, at least when I'm using it in a ViewController directly, but not with with my custom view. 滑块逻辑有效,至少在我直接在ViewController中使用滑块逻辑时有效,但不适用于我的自定义视图。 Specifically, the method specified in addTarget doesn't get called at all. 具体来说,根本不会调用addTarget中指定的方法。 I also tried setting the backgroundColor of the slider to something, and it actually showed up, meaning it has a frame. 我还尝试将滑块的backgroundColor设置为某种值,并且它实际上出现了,这意味着它具有框架。 So, what am I missing here? 那么,我在这里想念什么? I had a similar problem a lot of times with UIButton, etc. in custom UIView subclasses. 在自定义UIView子类中,UIButton等存在很多类似的问题。

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")
}
}

I really hope that someone can help me with this, as I've tried to figure this out for the past hours... and no solution :/ As I said, the method gets called when everything is inside a ViewController and its view, but not with the custom UIView. 我真的希望有人可以帮我解决这个问题,因为我在过去的几个小时里一直在努力解决这个问题……而且没有解决方案:/正如我所说,当所有内容都在ViewController及其视图内部时,该方法将被调用,但不能使用自定义UIView。

And by the way, the parentView property is the main view of the viewController, where the custom UIView gets initialized. 顺便说一句,parentView属性是viewController的主视图,自定义UIView在此初始化。 I initialize it with the empty constructor and then call show() with the ViewController's view. 我用空的构造函数初始化它,然后用ViewController的视图调用show()。

Thanks for your help! 谢谢你的帮助! - Robert -罗伯特

So, finally I got the solution... For everybody that faces the same issue: Look at your view hierarchy. 因此,终于有了解决方案……对于面临相同问题的每个人:查看您的视图层次结构。 I was missing the linkn between my popUpView and my customView, thats why the touch events weren't triggered properly. 我缺少popUpView和customView之间的链接,这就是为什么未正确触发触摸事件的原因。 Another mistake was that the popUp was never anchored properly and didn't have an own frame... That's why the slider wasn't operatable at all. 另一个错误是popUp从未正确锚定并且没有自己的框架...这就是为什么滑块根本不可操作的原因。 I hope this helps some of you guys! 希望对您有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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