UISlider 在 ViewDidLoad() 中没有子视图
UISlider no subviews in ViewDidLoad()
我想在 UISlider
的拇指上放一个 UILabel
。
我的代码是基于这个:Another SO question
问题在于,使用该代码,在更改值之前拇指上没有文本。所以我做了一些修改。我将标签设为全局变量,并在 viewDidLoad()
中对其进行配置。然后我只是在滑块更改值时更改文本。
实际问题是这样的(viewDidLoad()
中的代码):
let thumbView = mySlider.subviews.last
label.frame = (thumbView?.bounds)!
mySlider
的 subviews
数组为空。因此它会造成崩溃,因为我解包了一个 nil 值。
我不明白为什么会发生这种情况,因为视图已完全初始化。
为什么 mySlider.subviews
是空的?我错过了什么?有谁知道我该如何解决这个问题?有没有其他方法可以将标签放在拇指中间?
mySlider.subviews.last
不是获取 thumbImage 中心的可靠方法。文档中的任何地方都没有提到它。我个人认为那样做很老套。
但是,要获得 slider
的中心,您可以使用 trackRectForBounds
和 [=16= 的组合,基于 slider
的 value
进行计算].
这应该适合你:
@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
文本对齐设置为居中。
your linked question 中的代码工作正常,无需更改。
添加此方法,初始值将在您的 UISlider
:
上显示为 UILabel
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[mySlider sendActionsForControlEvents:UIControlEventValueChanged];
}
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
的拇指上放一个 UILabel
。
我的代码是基于这个:Another SO question
问题在于,使用该代码,在更改值之前拇指上没有文本。所以我做了一些修改。我将标签设为全局变量,并在 viewDidLoad()
中对其进行配置。然后我只是在滑块更改值时更改文本。
实际问题是这样的(viewDidLoad()
中的代码):
let thumbView = mySlider.subviews.last
label.frame = (thumbView?.bounds)!
mySlider
的 subviews
数组为空。因此它会造成崩溃,因为我解包了一个 nil 值。
我不明白为什么会发生这种情况,因为视图已完全初始化。
为什么 mySlider.subviews
是空的?我错过了什么?有谁知道我该如何解决这个问题?有没有其他方法可以将标签放在拇指中间?
mySlider.subviews.last
不是获取 thumbImage 中心的可靠方法。文档中的任何地方都没有提到它。我个人认为那样做很老套。
但是,要获得 slider
的中心,您可以使用 trackRectForBounds
和 [=16= 的组合,基于 slider
的 value
进行计算].
这应该适合你:
@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
文本对齐设置为居中。
your linked question 中的代码工作正常,无需更改。
添加此方法,初始值将在您的 UISlider
:
UILabel
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[mySlider sendActionsForControlEvents:UIControlEventValueChanged];
}
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
}
}