首页 > 解决方案 > 如何使我的自定义 ViewModifier 仅适用于 SwiftUI 中符合(可识别和视图)的内容/视图?

问题描述

我正在使我的 Identifiable图像这样的代码:

struct RedView: View, Identifiable {
    
    let id: UUID = UUID()
    
    var body: some View {

        Color.red.frame(width: 100, height: 100, alignment: .center)
        
        
    }
}

现在我想制作一个仅适用于或适用于它们的视图的CustomViewModifier ,例如,要制作普通的 ViewModifier,我们不需要我们的内容符合,它们必须符合,在这个问题/问题中,我想做一个要求其内容符合的CustomViewModifier和,我该怎么做?IdentifiableIdentifiableViewViewIdentifiable

到目前为止,这里有什么尝试,需要帮助来完成:

struct CustomViewModifier<InPutContent: View & Identifiable>: ViewModifier {

    func body(content: InPutContent) -> some View  {

        return content.onAppear() { print(content.id) }

    }

}

用例:

import SwiftUI

struct ContentView: View {

    var body: some View {

        RedView()
            .modifier(CustomViewModifier())  // It must work! because RedView is Identifiable!
        
        Text("Hello")
            .modifier(CustomViewModifier())  // It must NOT work! because Text is not Identifiable!
 
    }
}



更新:


struct CustomViewModifier<InPutContent: View & Identifiable>: ViewModifier {
    
    var inPutContent: () -> InPutContent

    func body(content: Content) -> some View  {

        return body2(content: inPutContent())

    }

    func body2(content: InPutContent) -> some View  {

        return content.onAppear() { print(content.id) }

    }

}

用例:

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        RedView()
            .modifier(CustomViewModifier(inPutContent: { RedView() }))       // compiles
        
        Text("Hello")
            .modifier(CustomViewModifier(inPutContent: { Text("Hello") }))   // does not compile
        
    }
}

标签: swiftswiftui

解决方案


One of the requirements of ViewModifier is that you are able to modify any view. Clearly, you cannot do that in this case, so ViewModifier is not suitable.

Try writing an extension on View where Self: Identifiable instead:

extension View where Self: Identifiable {
    func printId() -> some View  {
        return onAppear() { print(id) }
    }
}

usage:

struct ContentView: View {

    var body: some View {

        RedView()
            .printId()  // compiles
        
        Text("Hello")
            .printId()  // does not compile
 
    }
}

Comparison between ViewModifier and extensions


推荐阅读