【问题标题】:UIView: how does the appearance() proxy work?UIView:外观()代理如何工作?
【发布时间】:2021-12-01 16:46:36
【问题描述】:

我创建了一个简单的自定义UIView

final class TestView: UIView {
    var testColor: UIColor = .white {
        didSet {
            backgroundColor = testColor
        }
    }
}

然后我在我的视图控制器中写了这个:

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var testView: TestView!
    @IBOutlet weak var testView2: TestView!        
    
    override func viewDidLoad() {
        super.viewDidLoad()
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
            TestView.appearance().testColor = .red
        }
    }
}

这样做,我得到一个错误:

您能否帮助我了解这里出了什么问题以及如何为任何自定义 UIView 实现 UIAppearance 代理?

感谢您的帮助

【问题讨论】:

  • edit这个问题输入屏幕截图中的文本。然后,回答问题的人将能够引用文本或提出更正建议。文本将能够通过搜索找到。就目前而言,您的屏幕截图使您难以回答您的问题或有相关问题的人找到您的问题。

标签: ios uiview uiappearance


【解决方案1】:

您需要将属性设置为@objcdynamic

final class TestView: UIView {
    @objc dynamic var testColor: UIColor? = .white {
        didSet {
            backgroundColor = testColor
        }
    }
}

值得注意的是:UIAppearance 代理确实影响已经是视图层次结构一部分的视图。

因此,在您的示例中,将 @objc dynamic 添加到您的属性将消除崩溃,但您将不会看到两个 @IBOutlet 视图有任何变化。

如果您将其称为 viewDidLoad() 的一部分(而不是 DispatchQueue.main.asyncAfter):

override func viewDidLoad() {
    super.viewDidLoad()
    TestView.appearance().testColor = .red
}

两个@IBOutlet 视图获得红色背景。

或者,如果您向层次结构添加新视图,它将获得红色背景:

class AppearanceTestViewController: UIViewController {
    @IBOutlet weak var testView: TestView!
    @IBOutlet weak var testView2: TestView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
            TestView.appearance().testColor = .red
            self.addAnotherTestView()
        }
    }
    func addAnotherTestView() -> Void {
        let v = TestView()
        v.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(v)
        NSLayoutConstraint.activate([
            v.widthAnchor.constraint(equalToConstant: 240.0),
            v.heightAnchor.constraint(equalTo: v.widthAnchor),
            v.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            v.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        ])

        // this newly added view WILL have a red background
    }
}

【讨论】:

  • 其实很简单,谢谢!
猜你喜欢
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-01
  • 1970-01-01
相关资源
最近更新 更多