问题现已解决。 This answer显示基于工作解决方案的音频应用程序。
初步问题
我是Swift的新手并尝试创建一个UISliders
的银行来测试parameters of a physical model in AudioKit。每个UISlider
都有两个UILabels
,一个用于标识参数的名称,另一个用于显示当前UISlider
值。标签标识每个UISlider
及其对应的UIlabels.
虽然我可以在Xcode的调试区域中显示这些值,但我仍然试图在iPhone上的相应UISlider
中显示当前UILabel
值。当我向其slider.value
写lableForValue
时,除了奇怪的边缘条件(见底部的图)之外没有任何事情发生。
UISlider
值的日志清楚地显示它已收到已发送的值,并使用sender.tag
标识UISlider
发送的值。但新值永远不会出现在正确的UILabel.
解决方案
这是一个有效的解决方案,有望使其他一些Swift新手受益。已根据已接受的答案对下面的代码进行了更改。在将lableForValue
添加到subview
之前标记UILabels
允许UISlider.
更容易识别,并使用从UILabels
读取的值进行重写接受的答案也是一个简单的实际演示如何使用期权。已经确定了另一个边缘条件 - UILabel
将显示除第一个之外的所有滑块的值 - 并在最终编辑中进行更正。该代码还包含用于更改字体大小的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
}
}
扩展名。
Thank you PiyushRathi and dijipiji
最终修改
labelForID
UILabel + FontFiddler
此扩展名必须为labelForValue
和import UIKit
extension UILabel{
var defaultFont: UIFont? {
get { return self.font }
set { self.font = newValue }
}
}
UILabel
边缘条件
下面的屏幕截图显示移动任何滑块时最后⊥
会发生什么。无论移动哪个滑块或移动多远,显示的值始终为50.0。我知道当我禁用从滑块10读取值的语句时,条件会消失。但是,无论何时移动其他滑块,我都无法告诉UILabel for the 10的值是如何出现的。
答案 0 :(得分:1)
您好,您必须对代码进行一些更改:
您必须将unique tag
值传递给每个lableForValue
,以便在UIView中轻松找到它。
e.g。对于
在func makeValueLable(index: Int) -> UILabel
函数中添加标签lableForValue.tag = (index + 1) * 1000
将func sliderValueChanged(sender: UISlider){
更改为:
func sliderValueChanged(sender: UISlider) {
var valueLabel:UILabel? = nil;
for subview in view.subviews as [UIView] {
if subview.tag > 1000 {
let labelTag = subview.tag / 1000
if labelTag == sender.tag {
valueLabel = subview as? UILabel
break
}
}
}
if valueLabel != nil {
valueLabel!.text = String(sender.value)
}
}
希望这会有所帮助。
答案 1 :(得分:0)
看起来你有这些成员变量: var lableForValue:UILabel! var lableForID:UILabel!
在你的func makeValueLable中,你应该考虑创建一个新标签而不是引用成员变量。简而言之,您将为这些UILabel以及makeValueLable和makeIDLabel内部的成员变量创建新的实例: let labelForValue = UILabel() 让lablelFotID = UILabel() 等
注意 - 你拼写&#34;标签&#34; as&#34; lable&#34;很多:)
答案 2 :(得分:0)
以下是UISliders
如何用于更改物理建模音频合成中的参数的方法。您需要AudioKit.framework.
下载和使用它的说明here。
该模型本质上是一个混沌系统,用于合成滴水产生的声音。有些滑块比其他滑块更有效,但dampingFactor
激发了物理模型。一旦发生变化,可以听到一个孤立的滴水声,但是,就像标准的卫生设备一样,如果你摆弄它足够长的时间,你将会有一个稳定的滴水声,这可能很难(但并非不可能)停止。共振频率的三个滑块会影响声音的音高。
import UIKit
import AudioKit
class ViewController: UIViewController {
let drip = AKDrip()
var timer = Timer()
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 = 38
let valueLableTagOffset = 1000
let lables = ["intensity",
"dampingFactor",
"energyReturn",
"mainResFreq",
"1stResFreq",
"2ndResFreq",
"amplitude",
"rampTime",
"reserved",
"reserved"]
let loLimits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
let hiLimits = [100, 100, 100, 1000, 1000, 1000, 100, 100, 100, 100]
// [10.0, 2.9, 5.0, 750.0, 450.0, 600.0, 0.5, 1.0, 0, 0]
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)
}
// Physical Model Oscillator
AudioKit.output = drip
AudioKit.start()
drip.start()
}
func sliderValueChanged(sender: UISlider){
print("SLIDER", sender.tag, ":", sender.value)
var valueLabel: UILabel? = nil // clear UILabel
for subview in view.subviews as [UIView] { // find all subviews including labels
if subview.tag > valueLableTagOffset { // identify labels that show values
print(subview.tag)
let labelTag = subview.tag - valueLableTagOffset // get true tag by removing offset
print(labelTag)
if labelTag == sender.tag { // does tag match the slider that moved ?
valueLabel = subview as? UILabel // then this subview is the value label
break
}
}
}
if valueLabel != nil {
valueLabel!.text = String(sender.value) // so write slider value into its label
let paramValue = sender.value
let paramID = sender.tag
setDrip(paramValue: paramValue, paramID: paramID) // and write slider value into parameter
}
}
func setDrip(paramValue: Float, paramID: Int) {
switch paramID {
case 0:
drip.intensity = Double(paramValue) //10
case 1:
drip.dampingFactor = Double(paramValue) //2.9
case 2:
drip.energyReturn = Double(paramValue) //5
case 3:
drip.mainResonantFrequency = Double(paramValue) //750
case 4:
drip.firstResonantFrequency = Double(paramValue) //450
case 5:
drip.secondResonantFrequency = Double(paramValue) //600
case 6:
drip.amplitude = Double(paramValue) //0.5
case 7:
drip.rampTime = Double(paramValue) //1.0
default:
print("nothing to change for sliders 8 & 9")
}
}
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
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
if (lables[index] != "reserved") {
slider.value = slider.maximumValue / 2.0
slider.isContinuous = false
slider.addTarget(self, action: #selector(sliderValueChanged), for: UIControlEvents.valueChanged)
} else {
slider.value = 0
}
return slider
}
}
扩展程序1 UILabel + FontFiddler
import UIKit
extension UILabel{
var defaultFont: UIFont? {
get { return self.font }
set { self.font = newValue }
}
}
扩展名2 UIImage + DrawCircle
import UIKit
extension UIImage {
class func createThumbImage(size: CGFloat, color: UIColor) -> UIImage {
let layerFrame = CGRect(x: 0, y: 0, width: size, height: size)
let shapeLayer = CAShapeLayer()
shapeLayer.path = CGPath(ellipseIn: layerFrame.insetBy(dx: 1, dy: 1), transform: nil)
shapeLayer.fillColor = color.cgColor
shapeLayer.strokeColor = color.withAlphaComponent(0.65).cgColor
let layer = CALayer.init()
layer.frame = layerFrame
layer.addSublayer(shapeLayer)
return self.imageFromLayer(layer: layer)
}
class func imageFromLayer(layer: CALayer) -> UIImage {
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, UIScreen.main.scale)
layer.render(in: UIGraphicsGetCurrentContext()!)
let outputImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return outputImage!
}
}