将UILabel添加到子视图后如何重写UILabel?

时间:2016-12-14 08:55:38

标签: swift xcode uilabel uislider

问题现已解决。 This answer显示基于工作解决方案的音频应用程序。

初步问题

我是Swift的新手并尝试创建一个UISliders的银行来测试parameters of a physical model in AudioKit。每个UISlider都有两个UILabels,一个用于标识参数的名称,另一个用于显示当前UISlider值。标签标识每个UISlider及其对应的UIlabels.

虽然我可以在Xcode的调试区域中显示这些值,但我仍然试图在iPhone上的相应UISlider中显示当前UILabel值。当我向其slider.valuelableForValue时,除了奇怪的边缘条件(见底部的图)之外没有任何事情发生。

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

此扩展名必须为labelForValueimport UIKit extension UILabel{ var defaultFont: UIFont? { get { return self.font } set { self.font = newValue } } }

获取不同大小的字体

thank you Oleg Sherman

UILabel

边缘条件

下面的屏幕截图显示移动任何滑块时最后会发生什么。无论移动哪个滑块或移动多远,显示的值始终为50.0。我知道当我禁用从滑块10读取值的语句时,条件会消失。但是,无论何时移动其他滑块,我都无法告诉UILabel for the 10的值是如何出现的。

enter image description here

3 个答案:

答案 0 :(得分:1)

您好,您必须对代码进行一些更改:

  1. 您必须将unique tag值传递给每个lableForValue,以便在UIView中轻松找到它。

    e.g。对于 在func makeValueLable(index: Int) -> UILabel函数中添加标签lableForValue.tag = (index + 1) * 1000

  2. 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)
            }
        }
    
  3. 希望这会有所帮助。

答案 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

Thank you McMatan

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!
    }
}