将 UILabel 添加到子视图后如何重写? [英] How do I rewrite a UILabel after it is added to a subView?

查看:23
本文介绍了将 UILabel 添加到子视图后如何重写?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题现已解决.

解决方案

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

  1. 您必须向每个 lableForValue 传递一个 唯一标记 值,以便在 UIView 中轻松找到它.

    例如为了在 func makeValueLable(index: Int) -> 中添加标签UILabel 函数 put lableForValue.tag = (index + 1) * 1000

  2. func sliderValueChanged(sender: UISlider){ 更改为:

    func sliderValueChanged(sender: UISlider) {变量值标签:UILabel?= 无;用于 view.subviews 中的子视图为 [UIView] {如果 subview.tag >1000 {让 labelTag = subview.tag/1000如果 labelTag == sender.tag {valueLabel = 子视图为?用户界面标签休息}}}如果 valueLabel != nil {valueLabel!.text = String(sender.value)}}

希望这会有所帮助.

The problem is now fixed. This answer shows an audio application based on the working solution.

Initial question

I am new to Swift and trying to create a bank of UISliders to test parameters of a physical model in AudioKit. Each UISlider has two UILabels, one to identify the name of a parameter, the other to show a current UISlider value. Tags identify each UISlider and its corresponding UIlabels.

I am stuck trying to display current UISlider values in the corresponding UILabel on an iPhone although I can display these in the debug area in Xcode. When I write slider.value to its lableForValue nothing happens except a weird edge condition (see diagram at the bottom).

A log of UISlider values clearly showed it receiving a value sent and using sender.tag to identify which UISlider sent it. But the new value would never appear in the correct UILabel.

Solution

Here is a working solution that will hopefully benefit some other Swift novice. Changes based on the accepted answer have been made to the code below. Tagging lableForValue with a tag offset before adding it to subview allowed UILabels to be more easily identified and rewritten with values read from UISlider. The accepted answer is also a simple practical demonstration of how to use optionals. A further edge condition has been identified - UILabels would display values for all sliders except the first - and is corrected here in the final edit. The code also includes an extension of UILabel used to change the font size.

Thank you PiyushRathi and dijipiji


Final Edit

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

This extension is necessary to get a different sized font for labelForID and labelForValue

thank you Oleg Sherman

import UIKit

extension UILabel{
    var defaultFont: UIFont? {
        get { return self.font }
        set { self.font = newValue }
        }
    }

Edge Condition

The screen-shot below shows what happens to the last UILabel when any slider is moved. The value displayed is always 50.0 no matter which slider is moved or how far. I do know the condition disappears when I disable the statement that reads a value from slider 10. But I can't tell how a value of 50 always appears in the UILabel for slider 10 whenever other sliders are moved.

解决方案

Hi you have to do several changes in your code:

  1. You have to pass a unique tag value to each lableForValue so it can be found easily in UIView.

    e.g. for adding label in func makeValueLable(index: Int) -> UILabel function put lableForValue.tag = (index + 1) * 1000

  2. Change func sliderValueChanged(sender: UISlider){ to this:

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

hope this helps.

这篇关于将 UILabel 添加到子视图后如何重写?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆