【发布时间】:2016-12-14 08:55:38
【问题描述】:
问题现已解决。 This answer 展示了一个基于工作解决方案的音频应用程序。
初始问题
我是 Swift 新手,正在尝试创建一个 UISliders 库来测试 parameters of a physical model in AudioKit。每个UISlider 有两个UILabels,一个用于标识参数的名称,另一个用于显示当前的UISlider 值。标签识别每个UISlider 及其对应的UIlabels.
尽管我可以在 Xcode 的调试区域中显示这些值,但我仍试图在 iPhone 上的相应 UILabel 中显示当前的 UISlider 值。当我将slider.value 写入它的lableForValue 时,除了奇怪的边缘条件(参见底部的图表)之外,什么都没有发生。
UISlider 值的日志清楚地显示它接收到发送的值并使用sender.tag 来识别是哪个UISlider 发送的。但是新值永远不会出现在正确的UILabel.
解决方案
这是一个可行的解决方案,希望可以使其他一些 Swift 新手受益。 下面的代码已根据接受的答案进行了更改。在将lableForValue 添加到subview 之前使用标记偏移标记lableForValue 可以更容易地识别UILabels 并用从UISlider. 读取的值重写。接受的答案也是如何使用选项的简单实用演示。已经确定了进一步的边缘条件 - UILabels 将显示除第一个之外的所有滑块的值 - 并在最终编辑中进行了更正。该代码还包括UILabel 的扩展名,用于更改字体大小。
Thank you PiyushRathiand dijipiji
最终编辑
import UIKit
class ViewController: UIViewController {
var slider: UISlider!
var lableForValue: UILabel!
var lableForID: UILabel!
let defaultColour = UIColor.green
let highlightedColour = UIColor.lightGray
let thumbSize: CGFloat = 20
let topMargin = 75
let verticalSpacing = 50
let sliderWidth = 250
let sliderHeight = 24
let sliderToLabelSpace = 32
let valueLableTagOffset = 1000
let lables = ["intensity",
"dampingFactor",
"energyReturn",
"mainResFreq",
"1stResFreq",
"2ndResFreq",
"amplitude",
"reserved",
"reserved",
"reserved"]
let loLimits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
let hiLimits = [100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
override func viewDidLoad() {
super.viewDidLoad()
for index in 0..<10 {
let slider = makeSlider(index: index)
let IDLable = makeIDLable(index: index)
let valueLable = makeValueLable(index: index)
view.addSubview(slider)
view.addSubview(IDLable)
view.addSubview(valueLable)
}
}
func sliderValueChanged(sender: UISlider){
print("SLIDER", sender.tag, ":", sender.value)
var valueLabel: UILabel? = nil
for subview in view.subviews as [UIView] {
if subview.tag > valueLableTagOffset {
print(subview.tag)
let labelTag = subview.tag - valueLableTagOffset
// Edge condition: UILabels display values for all sliders except the first
// Fix: use '- valueLableTagOffset', not '/ valueLableTagOffset'
print(labelTag)
if labelTag == sender.tag {
valueLabel = subview as? UILabel
break
}
}
}
if valueLabel != nil {
valueLabel!.text = String(sender.value)
}
}
func makeHighlightedImage() -> (UIImage) {
let size = thumbSize
let highlightedStateImage = UIImage.createThumbImage(size: size, color: highlightedColour)
return (highlightedStateImage)
}
func makeDefaultImage() -> (UIImage) {
let size = thumbSize
let defaultStateImage = UIImage.createThumbImage(size: size, color: defaultColour)
return (defaultStateImage)
}
func makeValueLable(index: Int) -> UILabel {
let x = Int(view.frame.midX) - (sliderWidth / 2)
let y = Int(topMargin + (verticalSpacing * index) - sliderToLabelSpace)
let w = sliderWidth
let h = sliderHeight
lableForValue = UILabel(frame: CGRect(x: x, y: y, width: w, height: h))
lableForValue.tag = (index + 1) + valueLableTagOffset
// Edge condition: UILabels display values for all sliders except the first
// Fix: use '+ valueLableTagOffset', not '* valueLableTagOffset'
lableForValue.textColor = defaultColour
lableForValue.textAlignment = NSTextAlignment.center
lableForValue.text = String(index + 1)
return lableForValue
}
func makeIDLable(index: Int) -> UILabel {
let x = Int(view.frame.midX) - (sliderWidth / 2)
let y = Int(topMargin + (verticalSpacing * index) - 32)
let w = sliderWidth
let h = sliderHeight
lableForID = UILabel(frame: CGRect(x: x, y: y, width: w, height: h))
lableForID.tag = index + 1
lableForID.textColor = highlightedColour
lableForID.textAlignment = NSTextAlignment.left
lableForID.defaultFont = UIFont(name: "HelveticaNeue", size: CGFloat(12))
lableForID.text = lables[index]
return lableForID
}
func makeSlider(index: Int) -> UISlider {
let x = view.frame.midX
let y = CGFloat(topMargin + (verticalSpacing * index))
let w = sliderWidth
let h = sliderHeight
slider = UISlider(frame: CGRect(x: 0, y: 0, width: w, height: h))
slider.center = CGPoint(x: x, y: y)
slider.minimumValue = Float(loLimits[index])
slider.minimumTrackTintColor = defaultColour
slider.maximumValue = Float(hiLimits[index])
slider.maximumTrackTintColor = highlightedColour
slider.tag = index + 1
slider.value = slider.maximumValue / 2.0
slider.isContinuous = false
slider.addTarget(self, action: #selector(sliderValueChanged), for: UIControlEvents.valueChanged)
return slider
}
}
UILabel+FontFiddler
此扩展是为labelForID 和labelForValue 获得不同大小的字体所必需的
import UIKit
extension UILabel{
var defaultFont: UIFont? {
get { return self.font }
set { self.font = newValue }
}
}
边缘条件
下面的屏幕截图显示了当任何滑块移动时最后一个UILabel 会发生什么。无论移动哪个滑块或移动多远,显示的值始终为 50.0。我确实知道当我禁用从滑块 10 读取值的语句时条件会消失。但我无法判断每当其他滑块移动时滑块 10 的 UILabel 中总是出现 50 的值。
【问题讨论】:
-
我认为您需要在标签中显示滑块更改的值?
-
在你的代码中,当滑块值改变时,你直接将字符串赋值给
lableForValue,这是你添加到View的最后一个标签,你需要先根据滑块标签取Label,然后赋值给它串起来。 -
@PiyushRathi,Piyush,我想你已经发现了问题所在。查看我的编辑,如果您提交带有解决方案的答案,我将接受它。谢谢
标签: swift xcode uilabel uislider