【问题标题】:Using Custom UIKit Classes in SwiftUI在 SwiftUI 中使用自定义 UIKit 类
【发布时间】:2021-07-17 16:20:36
【问题描述】:

我已经为 UIKit 对象创建了自己的自定义类。现在我想在 SwiftUI 中使用相同的类,我该如何实现以及需要付出多少努力。

另外,如果我愿意,我需要在 swift UI 中编写相同的类。

例如,我有自定义的 UILable 子类 WMLabel。

    class WMLabel: UILabel {
    var myproperty: String = "" {
        didSet {
            self.text = myproperty
        }
    }
}

那么我如何在 swiftUI 中使用 WMLabel?

我尝试了ObserverableObjectUIViewRepresentable,但无法访问属性。

【问题讨论】:

    标签: swift swiftui uikit


    【解决方案1】:

    您绝对可以使用您的 UIKit 类。要获得对属性的基本访问权限,您需要查看 makeUIView(在首次创建视图时发生)和 updateUIVew

    使用您的示例代码:

    class WMLabel: UILabel {
        var myproperty: String = "" {
            didSet {
                self.text = myproperty
            }
        }
    }
    
    struct WMLabelRepresented: UIViewRepresentable {
        var text : String
        
        func makeUIView(context: Context) -> WMLabel {
            return WMLabel()
        }
        
        func updateUIView(_ uiView: WMLabel, context: Context) {
            uiView.myproperty = text
        }
    }
    
    struct ContentView : View {
        var body: some View {
            WMLabelRepresented(text: "My text")
        }
    }
    

    如果有些事情不能以声明的方式表达,您将需要查看协调器,正如您所提到的,可以使用ObservableObject 以命令式方式将数据传达给您的视图,但通常您可以找到表达大部分内容的方法声明式的事情。

    如果你想要一个更复杂的命令式通信的例子,这里有几个链接到我的另一个答案:

    【讨论】:

    • 大声笑,我采取了懒惰的方式解决这个问题。我宁愿尽可能转换为 SwiftUI。很好的答案!
    • 如果我在 WMLable 中有 20 个属性,我需要在 WMRepresented 中的所有属性,并且在初始化时需要所有属性?
    • 不一定。请参阅我的这个答案 (stackoverflow.com/a/67199225/560942) 以获取一个示例,其中您在父视图和UIViewRepresentable 共享的单独类中持有对UIView 的引用——它允许任一实体进行命令式访问。
    • 如果我在 WMLabel 中有另一个属性说“foregroundColor”,那么我如何在 contentView 中使用它而不在 WMLabelRepresented 中添加它。或者如果我需要在 WMLabelRepresented 中添加它,那么我如何在 contentView 中单独使用它(不在初始化程序中使用)
    • 为什么你不想在初始化器中使用它?
    【解决方案2】:

    如果您有几个自定义类,那么转换所有自定义类并与它们交互将是一件非常麻烦的事。你最终会使用一个叫做UIViewRepresentable 的东西,它需要很多东西,其中最烦人的就是协调器。将类重写为 SwiftUI 版本几乎会更好。这是 Apple 关于将 SwiftUI 与 UIKit 接口的文档:https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit

    这是将该 UILabel 转换为 SwiftUI 的示例,具有可访问的属性。

    转换示例

    struct WMLabel: View {
        var myProperty: String
        var body: some View {
            Text(myProperty)
        }
    }
    

    示例用法

    struct Example: View {
        var body: some View {
            WMLabel(myProperty: "Hello World!")
        }
    }
    

    如您所见,将某些内容转换为 SwiftUI 涉及的代码很少,如果您开始参与 UIViewRepresentable,则必须开始使用协调器和一堆其他接口方法才能使其正常工作。有时它是必需的,但在大多数情况下,我会尽量避免它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 2022-08-05
      • 2021-10-09
      • 1970-01-01
      • 2019-10-21
      • 2021-10-16
      • 2020-12-16
      相关资源
      最近更新 更多