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

Posted

技术标签:

【中文标题】如何使我的自定义 ViewModifier 仅适用于 SwiftUI 中符合(可识别和视图)的内容/视图?【英文标题】:How can I make my custom ViewModifier works only on Contents/Views that conform (Identifiable and View) in SwiftUI? 【发布时间】:2021-03-20 07:14:14 【问题描述】:

我正在制作我的 View Identifiable 像这样的代码:

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

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

现在我想制作一个 CustomViewModifier,它只适用于或适用于 Views,它们是 Identifiable,例如制作正常的 ViewModifier,我们不需要我们的内容符合Identifiable,它们必须符合View,在这个question/problem我想做一个 CustomViewModifier 要求它的内容符合ViewIdentifiable,我该怎么做?

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

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
        
    

【问题讨论】:

见this。你无法决定Content 是什么。 @Sweeper:我知道,这就是为什么我要制作 CustomViewModifier,在它们传递到 CustomViewModifier 之前我可以通过我的内容看到它跨度> @Sweeper:我添加了一些新代码来告诉你我想要什么 你好像没听懂。你在这里试图加强前提条件,这是你绝对做不到的。协议告诉你“要符合我的要求,你必须实现一个接受某种 View 的方法”,但你坚持说“不,我只会提供一个接受 identifiable的方法>View"。你现在明白你为什么不讲理了吗? 使用ViewModifier 而是使用View where Self: Identifiable 的普通旧extension 怎么样? 查看我第一条评论中的链接。它应该解释Content 的声明位置。 【参考方案1】:

ViewModifier 的要求之一是您能够修改任何 视图。显然,在这种情况下你不能这样做,所以ViewModifier 不合适。

尝试在 View where Self: Identifiable 上编写扩展程序:

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

用法:

struct ContentView: View 

    var body: some View 

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

Comparison between ViewModifier and extensions

【讨论】:

以上是关于如何使我的自定义 ViewModifier 仅适用于 SwiftUI 中符合(可识别和视图)的内容/视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何使我的自定义对象 Parcelable?

在 XAML 中调用时,如何使我的自定义依赖项属性排序到顶部?

如何使我的自定义 HTML 小部件针对不同的屏幕尺寸显示不同?

mvc(QSortFilterProxyModel)中的自定义排序仅适用一次

如何修复横向截止的自定义 SearchView 背景?

Swiftui Scrollview Viewmodifier 适用于所有 Scrollview