【问题标题】:Setting/Changing variables of a nested custom UIView in another custom UIView在另一个自定义 UIView 中设置/更改嵌套自定义 UIView 的变量
【发布时间】:2016-06-17 10:04:07
【问题描述】:

我目前遇到了嵌套在其他自定义 UIView 中的自定义 UIView 的问题,嵌套自定义 UIView 的变量无法更改,因此无法反映在视图本身中。

目前,我有 3 个自定义 UIView:

TokenView,它只覆盖了 drawRect 以创建一个带有圆形图像的视图。

@IBDesignable class TokenView: UIView {

@IBInspectable var tokenOutlineColor: UIColor = UIColor.blackColor()
@IBInspectable var tokenBackgroundColor: UIColor = UIColor.lightGrayColor()
@IBInspectable var tokenImage: UIImage!

override init(frame: CGRect){
    super.init(frame:frame)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

override func drawRect(rect: CGRect) {

    var context = UIGraphicsGetCurrentContext()

    var thickness: CGFloat = 3
    var path = UIBezierPath(ovalInRect: CGRect(origin: CGPointMake(thickness/2, thickness/2), size: CGSize(width: rect.width - thickness, height: rect.height - thickness)))

    CGContextSaveGState(context)
    path.addClip()

    tokenOutlineColor.setStroke()
    tokenBackgroundColor.setFill()
    path.fill()
    if let image = tokenImage {
        tokenImage.drawInRect(rect)
    }
    path.stroke()

    }
}

PersonView,它有一个 TokenView() 作为子视图,当我更改我所说的 TokenView 的变量时,它也可以按预期工作。

class PersonView: UIView {

var name: String?
var group: PersonGroup?

required init?(coder aDecoder: NSCoder){
    super.init(coder: aDecoder)
    makePersonView()
}

override init(frame: CGRect) {
    super.init(frame: frame)
    makePersonView()
}

func makePersonView(){

    if name == nil {
        self.name = "Bob"
    }
    if group == nil {
        self.group = PersonGroup.Good
    }

    let token = TokenView()
    token.translatesAutoresizingMaskIntoConstraints = false

    switch group! {
    case .Good:
        token.tokenOutlineColor = UIColor.greenColor()
    case .Bad:
        token.tokenOutlineColor = UIColor.redColor()
    default:
        token.tokenOutlineColor = UIColor.blueColor()
    }
    token.tokenImage = UIImage(named: name!)
    token.tokenBackgroundColor = UIColor.clearColor()
    token.backgroundColor = UIColor.clearColor()        
    addSubview(token)

    let label = UILabel()
    label.text = name
    label.translatesAutoresizingMaskIntoConstraints = false
    label.textAlignment = NSTextAlignment.Center
    addSubview(label)

    NSLayoutConstraint.activateConstraints([
        token.topAnchor.constraintEqualToAnchor(topAnchor),
        token.leadingAnchor.constraintEqualToAnchor(leadingAnchor),
        token.trailingAnchor.constraintEqualToAnchor(trailingAnchor),
        token.heightAnchor.constraintEqualToConstant(frame.size.height*0.70),
        token.bottomAnchor.constraintEqualToAnchor(label.topAnchor),
        label.leadingAnchor.constraintEqualToAnchor(leadingAnchor),
        label.trailingAnchor.constraintEqualToAnchor(trailingAnchor),
        label.bottomAnchor.constraintEqualToAnchor(bottomAnchor)
        ])
}

和DetailedPersonView 类,由此创建PersonView 实例并从那里修改其变量,这就是问题所在。其他添加的“详细信息”工作正常,只是在类中的函数中修改时嵌套的 PersonView 中的那些。

class DetailedPersonView: UIView {

var name: String = "Marley"
var group: PersonGroup = PersonGroup.Bad

var quantity: Float = 0.00
var stat: String? = "Strength"

required init?(coder aDecoder: NSCoder){
    super.init(coder: aDecoder)
    makeDetailedPersonView()

}

override init(frame: CGRect) {
    super.init(frame: frame)
    makeDetailedPersonView()
}

func makeDetailedPersonView(){
    let personView = PersonView()
    personView.translatesAutoresizingMaskIntoConstraints = false
    personView.name = name
    personView.group = group
    personView.type = type
    addSubview(personView)

    let label = UILabel()
    let quantityString = String(format: quantity == floor(quantity) ? "%.0f":"%.1f", quantity)
    if unit != nil {
        label.text = quantityString + " " + stat!
    } else {
        label.text = quantityString
    }
    label.translatesAutoresizingMaskIntoConstraints = false
    label.textAlignment = NSTextAlignment.Center

    addSubview(label)

    NSLayoutConstraint.activateConstraints([
        personView.topAnchor.constraintEqualToAnchor(topAnchor),
        personView.leadingAnchor.constraintEqualToAnchor(leadingAnchor),
        personView.trailingAnchor.constraintEqualToAnchor(trailingAnchor),
        personView.bottomAnchor.constraintEqualToAnchor(label.topAnchor),
        label.leadingAnchor.constraintEqualToAnchor(leadingAnchor),
        label.trailingAnchor.constraintEqualToAnchor(trailingAnchor),
        label.heightAnchor.constraintEqualToConstant(frame.size.height*0.25),
        label.bottomAnchor.constraintEqualToAnchor(bottomAnchor)
        ])

}


}

所以目前我的DetailedPersonView 的TokenView(嵌套在PersonView 中)显示了PersonView 的默认tokenName 和tokenImage,即“Bob”,反映PersonGroup.Bad 的圆圈轮廓也是如此。

我尝试使用 PersonView 的自定义 init 方法,尝试使用DetailedPersonView 的变量初始化DetailedPersonView 中的PersonView,但成功有限。

理想情况下,这个自定义子视图应该类似于 UILabel 的工作方式,其中 UILabel().text 会随着变量的变化而更改视图中的文本,如果这有意义的话。

目前还没有找到解决这个问题的明确方法:\

感谢您阅读此问题! :D

编辑: 我认为可能有效的一种解决方法是为自定义 UIView 实现一个类方法来重置每个子视图的内容,并在每次更改变量时调用它。或者委托中是否已经有一个可以实现相同结果的函数,并且在视图更改时被调用?

【问题讨论】:

    标签: swift variables uiview nested


    【解决方案1】:

    您正在更改子视图的属性,但没有将这些更改传播到依赖这些属性的子视图。这通常通过属性观察来快速完成。有关更多信息,请参阅财产观察员部分here。但是您可以使用didSetobserver 来传播您的更改。例如,在您的 PersonView 类中,您应该首先保留对它的引用 TokenView 子视图 var tokenView:TokenView? 并且它是 UILabel subviewvar nameLabel:UILabel?and set them equal to theTokenViewandUILabelyou create inmakePersonView`。然后在名称上添加属性观察:

        var name: String?{
            didSet{
                if let image = UIImage(named: name!)
                {
                    self.tokenView?.tokenImage = image
                    self.nameLabel?.text = name
                    self.tokenView?.setNeedsDisplay()
                }
            }
        }
    

    这样DetailPersonView 对名称的任何更改都会自动更改TokenView's 图像。

    tokenImagetokenOutlineColor 类似,您需要在每次设置它们时重新绘制视图。

       @IBInspectable var tokenOutlineColor: UIColor = UIColor.blackColor(){
            didSet{
                self.setNeedsDisplay()
            }
        }
        @IBInspectable var tokenImage: UIImage!{
            didSet{
                self.setNeedsDisplay()
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-15
      相关资源
      最近更新 更多