自定义UIView:未调用UIButton addTarget [英] Custom UIView: UIButton addTarget not called

查看:90
本文介绍了自定义UIView:未调用UIButton addTarget的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是我有一个自定义UIView,它代表一个弹出窗口.在此视图内,我希望有一个滑块,该滑块的标签每次我拖动滑块时都会更新.滑块逻辑有效,至少在我直接在ViewController中使用滑块逻辑时有效,但不适用于我的自定义视图.具体来说,根本不会调用addTarget中指定的方法.我还尝试将滑块的backgroundColor设置为某种值,并且实际上显示出来,这意味着它具有框架.那么,我在这里想念的是什么?在自定义UIView子类中,UIButton等存在很多类似的问题.

My problem is that I have a custom UIView, which is representing a popup. 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. Specifically, the method specified in addTarget doesn't get called at all. I also tried setting the backgroundColor of the slider to something, and it actually showed up, meaning it has a frame. So, what am I missing here? I had a similar problem a lot of times with UIButton, etc. in custom UIView subclasses.

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.

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.

顺便说一句,parentView属性是viewController的主视图,自定义UIView在此初始化.我使用空的构造函数对其进行初始化,然后使用ViewController的视图调用show().

And by the way, the parentView property is the main view of the viewController, where the custom UIView gets initialized. I initialize it with the empty constructor and then call show() with the ViewController's view.

感谢您的帮助! -罗伯特

Thanks for your help! - Robert

推荐答案

最后,我得到了解决方案...对于面临相同问题的每个人:查看您的视图层次结构.我缺少popUpView和customView之间的链接,这就是为什么未正确触发触摸事件的原因.另一个错误是popUp从未正确锚定并且没有自己的框架...这就是为什么滑块根本不可操作的原因. 希望对您有所帮助!

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. 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. I hope this helps some of you guys!

这篇关于自定义UIView:未调用UIButton addTarget的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆