Swift4中代码创建的UISlider点击事件无法引用滑块的问题
解决UISlider点击手势中Selector无法引用Slider的问题
嗨,我来帮你搞定这个问题!你遇到的核心问题是手势识别器的Selector参数格式不符合系统规则,以及如何正确获取点击对应的Slider,下面一步步给你拆解:
1. 修正手势的Selector写法
UITapGestureRecognizer的回调方法默认只能接收一个参数(就是手势识别器本身),你之前试图在Selector里传递slider作为第二个参数,这不符合系统的回调逻辑,也是导致报错的关键原因之一。
修改创建手势的代码:
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(sliderTapped(_:))) slider.addGestureRecognizer(tapGestureRecognizer)
2. 重写回调方法,从手势中获取对应的Slider
既然不能直接传Slider参数,我们可以通过手势识别器的view属性来获取它绑定的Slider(因为手势是添加到Slider上的),这样就不会出现"slider未初始化"的问题了。同时还可以简化你原来的计算逻辑(Slider是水平控件,只需要关注x轴的点击位置即可,不用计算距离):
@objc func sliderTapped(_ gestureRecognizer: UIGestureRecognizer) { // 先确保手势的view是UISlider,避免强制转换出错 guard let slider = gestureRecognizer.view as? UISlider else { return } let pointTapped = gestureRecognizer.location(in: assessView) let sliderOriginInAssessView = slider.convert(slider.bounds.origin, to: assessView) let sliderWidth = slider.bounds.width // 计算点击位置相对于Slider的x轴偏移量 let relativeTapX = pointTapped.x - sliderOriginInAssessView.x // 根据偏移量计算对应的Slider值 var newValue: CGFloat if relativeTapX < 0 { newValue = 0 } else if relativeTapX > sliderWidth { newValue = CGFloat(slider.maximumValue) } else { newValue = (relativeTapX / sliderWidth) * CGFloat(slider.maximumValue) } slider.setValue(Float(newValue), animated: true) }
3. 关于手势目标的疑问
你不需要把手势的目标设置为assessView,保持target: self(当前ViewController)就完全没问题。因为手势是绑定在Slider上的,当用户点击Slider时,手势会触发并调用目标对象(也就是你的ViewController)的回调方法,这样的逻辑是正确的。
内容的提问来源于stack exchange,提问作者Kasper Olsen
相关产品推荐
相关产品推荐

