UISlider 在 ViewDidLoad() 中没有子视图

Posted

技术标签:

【中文标题】UISlider 在 ViewDidLoad() 中没有子视图【英文标题】:UISlider no subviews in ViewDidLoad() 【发布时间】:2016-07-16 15:55:33 【问题描述】:

我想在UISlider 的拇指上加上一个UILabel

我的代码基于此:Another SO question

问题在于,使用该代码,在您更改值之前,拇指上没有文字。所以我做了一些修改。我将标签设为全局变量,并在viewDidLoad() 中配置它。然后我只是在滑块更改值时更改文本。

实际问题是这样的(viewDidLoad() 中的代码):

let thumbView = mySlider.subviews.last
label.frame = (thumbView?.bounds)!

mySlidersubviews 数组为空。因此它会导致崩溃,因为我打开一个 nil 值。

我不明白为什么会发生这种情况,因为视图已完全初始化。

为什么mySlider.subviews 是空的?我错过了什么?有谁知道我该如何解决这个问题?有没有其他方法可以将标签放在拇指中间?

【问题讨论】:

您的视图已完全初始化,但滑块的子视图不一定。 thumbView 可能是延迟实例化的,所以它还没有在viewDidLoad 中创建,因为它还没有被调用。您应该使用@Zac Kwan 的建议来避免直接操作滑块的视图层次结构。 @beyowulf 有没有办法强制初始化? 【参考方案1】:

mySlider.subviews.last 不是获取 thumbImage 中心的可靠方法。文档中的任何地方都没有提及。我个人认为那样做是很老套的。

但是,要获得slider 的中心,您可以使用trackRectForBoundsthumbRectForBounds 的组合基于valuevalue 进行计算。

这应该适合你:

@IBAction func sliderValueChanged(slider: UISlider) 
    let trackRect = slider.trackRectForBounds(slider.bounds)
    let thumbRect = slider.thumbRectForBounds(slider.bounds, trackRect: trackRect, value: slider.value)

    sliderLabel.center = CGPointMake(thumbRect.origin.x + thumbRect.size.width / 2 + slider.frame.origin.x, slider.frame.origin.y + thumbRect.size.height / 2)

基本上,它的作用是首先计算轨道的矩形,然后使用它来计算 thumbRect。最后设置中心,考虑滑块的宽度和高度以及拇指大小。

记得将 label 文本对齐设置为居中。

【讨论】:

它确实有道理,但它不起作用。我将您的代码放在viewDidLoad() 中作为初始值,并将您的代码放在值更改时的函数中。问题在于: 1. 标签略高于拇指。 2.如果我改变值,标签不会移动。 我稍微摆弄了一下,我设法让标签停留在拇指上(我之前修改了滑块以逐步工作/捕捉到值),但它仍然高于拇指和这真的很奇怪。我有另一个滑块,其中拇指被修改为 160x30pts,标签留在滑块的 x 原点。 这并不能解决 OP 的问题,它所做的只是用另一个 hack 替换一个获取中心的 hack。在viewDidLoad() 方法中加载滑块后,标签仍然不会显示,这是 OP(和我)正在寻找的。​​span> 【参考方案2】:

your linked question 的代码工作正常,无需更改。

添加此方法,初始值将在您的UISlider 上显示为UILabel

- (void)viewDidLayoutSubviews 
    [super viewDidLayoutSubviews];

    [mySlider sendActionsForControlEvents:UIControlEventValueChanged];

【讨论】:

【参考方案3】:
class ThumbTextSlider: UISlider 
 var thumbTextLabel: UILabel = UILabel()
 var passedValue = 0

 private var thumbFrame: CGRect 
     return thumbRect(forBounds: bounds, trackRect: trackRect(forBounds: 
  bounds), value: value)
 

 override func layoutSubviews() 
     super.layoutSubviews()

     thumbTextLabel.frame = thumbFrame
     thumbTextLabel.text = String(passedValue)
 

 override func awakeFromNib() 
     super.awakeFromNib()
     addSubview(thumbTextLabel)
     setThumbImage(#imageLiteral(resourceName: "icon-settings"), for: .normal)
     thumbTextLabel.font = UIFont(name: "SFProText-Semibold", size: 16)
     thumbTextLabel.textAlignment = .center
     thumbTextLabel.layer.zPosition = layer.zPosition + 1
 

【讨论】:

以上是关于UISlider 在 ViewDidLoad() 中没有子视图的主要内容,如果未能解决你的问题,请参考以下文章

UISlider布局忽略宽度

Swift - UISlider

UI控件(UISlider)

UIPageControl,UISlider

AVPlayer seekToTime 不正确使用 UISlider

UISlider addTarget 和 sendActions 在 UT 中不起作用