gpt4 book ai didi

swift - 在另一个自定义 UIView 中设置/更改嵌套自定义 UIView 的变量

转载 作者:行者123 更新时间:2023-11-28 12:46:36 26 4
gpt4 key购买 nike

我目前遇到嵌套在其他自定义 UIView 中的自定义 UIView 的问题,嵌套的自定义 UIView 的变量无法更改,因此反射(reflect)在 View 本身中。

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

TokenView,它只重写了 drawRect 以创建带有圆形图像的 View 。

@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() 作为 subview ,并且在我更改所述 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”,反射(reflect) PersonGroup.Bad 的圆圈轮廓也是如此。

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

理想情况下,此自定义 subview 的工作方式应与 UILabel 的工作方式类似,其中 UILabel().text 在其变量更改时更改其 View 中的文本,如果这有意义的话。

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

感谢您阅读这个问题! :D

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

最佳答案

您正在更改 subview 的属性,但没有将这些更改传播到依赖于这些属性的 subview 。在 swift 中,这通常是通过属性观察来完成的。请参阅属性观察员部分 here获取更多信息。但是您可以使用 didSet 观察器来传播您的更改。例如,在您的 PersonView 类中,您应该首先保留对它的 TokenView subview var tokenView:TokenView? 和它的 UILabel subview 的引用var nameLabel:UILabel?并将它们设置为等于您在makePersonView` 中创建的TokenViewUILabel。然后在名称上添加属性观察:



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

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

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

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

关于swift - 在另一个自定义 UIView 中设置/更改嵌套自定义 UIView 的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37878703/

26 4 0
文章推荐: ios - HealthKit 使用回退方法锚定查询?
文章推荐: JavaScript - 如何获取字符串中的特定值?
文章推荐: javascript - JQuery:每 5 秒更改
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com