从外部引用设置属性上的 .attributedText(可通过 NIB 加载的 UIView 内的插座访问)似乎失败

Posted

技术标签:

【中文标题】从外部引用设置属性上的 .attributedText(可通过 NIB 加载的 UIView 内的插座访问)似乎失败【英文标题】:Setting .attributedText on properties (accessible via outlets inside NIB-loaded UIView) from external reference appears to fail 【发布时间】:2019-10-22 02:47:32 【问题描述】:

笔尖已通过UINib(nibName, bundle).instantiate()手动加载。

将笔尖连接到UIView 子类的插座正在成功初始化并且可以访问。

其中两个出口代表UILabelUITextView - 用于呈现属性文本字符串。

在通过.attribtedText setter 方法替换之前,在可变副本上对属性字符串进行更改。

只要在 UIView 子类或加载 nib 的 View Controller 中直接调用旨在更新属性文本的函数,一切都会按预期工作。

但是,当通过代码库其他地方的某个其他类对象中保存的引用调用相同的函数时,不会发生更新。

Nib 的 UIView 子类:

class MyView: UIView             

    @IBOutlet weak var aLabel: UILabel!
    @IBOutlet weak var someText: UITextView!

    ...

    public func applySomeStyle() 

        guard
            let aLabelMAS = aLabel.attributedText?.mutableCopy() as? NSMutableAttributedString,
            var someTextMAS = someText.attributedText.mutableCopy() as? NSMutableAttributedString
        else 
            return
        

        let labelRange = NSRange(location: 0, length: aLabelMAS.length)
        aLabelMAS.addAttribute(.backgroundColor, value: UIColor.yellow, range: labelRange)

        let someTextRange = NSRange(location: 0, length: someTextMAS.length)
        someTextMAS.removeAttribute(.backgroundColor, range: someTextRange)

        aLabel.attributedText = aLabelMAS
        someText.attributedText = someTextMAS

    

    public func doStuff() 

        ...

        applySomeStyle() // No problems -- the attributed strings inside the UILabel and UITextView are updated as intended.

        ...
    


从加载 Nib 的 ViewController 内部,通过对 MyView 对象的引用调用 applySomeStyle 函数可以正常工作。

class MyViewController: UIViewController 

    weak var myView: MyView!

    override func viewDidLoad() 
        super.viewDidLoad()
        ...
        myView = UINib(nibName: "MyView", bundle: Bundle.main).instantiate(
                withOwner: self, options: nil).first as? MyView
        self.view.addSubview(myView)
        ...
    

    override func viewDidLayoutSubviews() 
        super.viewDidLayoutSubviews()
        myView.applySomeStyle()  // Again, no problems.
    


但如果 nib 类对象在其他地方被引用——则不会发生更改。

class SomeOtherViewController: UIViewController

    var myVC: MyViewController!

    ...


    func foo() 
        myVC.myView.applySomeStyle() // Fails to update the UILabel/UITextView
    


    ...


【问题讨论】:

我发现了问题所在。我忘记了在网点上设置属性文本属性会触发对 viewDidLayoutSubview 的调用,这会恢复一些我希望在另一个函数中更改的样式。 【参考方案1】:

执行attributedText setter,即

someText.attributedText = someNewAttributedString

触发viewDidLayoutSubviews()

viewDidLayoutSubviews() 中,我正在调用一个函数(例如“加载内容”函数),该函数还负责设置一些字符串属性。我使用布尔标志来确保对viewDidLayoutSubviews 的后续调用不会再次触发该函数。

在这种情况下,该布尔条件未按预期工作,因此设置 attributedText 属性的其他函数导致它再次被触发,覆盖其他函数所做的更改。

我以为我正在处理一个不起眼的错误。 我想可能是线程问题。 我想这可能是某种损坏的参考。

我想错了。

但我希望这对外面的人有用。

【讨论】:

以上是关于从外部引用设置属性上的 .attributedText(可通过 NIB 加载的 UIView 内的插座访问)似乎失败的主要内容,如果未能解决你的问题,请参考以下文章

C#中导入外部dll文件,如果不放在当前目录下,通过设置工程属性-引用路径选项卡添加文件路径,为何报错啊

java内部类如何被外部引用

使用外部文件中的模型填充 Mongoose 模式属性

Spring Boot 将 Java 注释上的配置属性/消息外部化

如何从另一个 sbt 项目中引用外部 sbt 项目?

如何从外部 api 读取属性并将其设置为 springboot 中的应用程序上下文以使其全局可用?