如何将函数中的多个修饰符应用于 SwiftUI 中的给定视图?

Posted

技术标签:

【中文标题】如何将函数中的多个修饰符应用于 SwiftUI 中的给定视图?【英文标题】:How to apply multiple modifier in a function to a given View in SwiftUI? 【发布时间】:2022-01-09 05:35:06 【问题描述】:

我有一个带有这个签名的函数(我认为它的功能非常简单),实现对我们来说并不重要:

extension View 
    func border(edge: Edge, color: Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View

然后我想扩展View的功能,并添加一个额外的函数来调用之前的函数:

extension View 
    func border(edges: [Edge], color: Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View

但我的第一个想法没有奏效。在 UIKit 中不会有问题,但在这里我无法弄清楚如何在单个函数中应用多个(可变数量)修饰符。

我试过这个:

extension View 
   func border(edges: [Edge], color: Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View 
        var view = self
        edges.forEach  edge in
            view = view.border(edge: edge, color: color, width: width, cornerRadius: cornerRadius)
        
        return view
    

它显示了 2 个错误:

无法将“某些视图”类型的值分配给“自我”类型

实例方法'border(edges:color:width:cornerRadius:)'的返回类型要求'Self'符合'View'

我理解错误,但我不能说让view 变量成为some Viewvar view: View = self 无法编译)。我如何(用什么语法/想法)解决这个问题?

编辑:这是一个完整的代码,它显示了问题:

extension SwiftUI.View 
    // not completed implementation, doesn't matter
    public func border(edge: Edge, color: SwiftUI.Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some SwiftUI.View 
        self
    

    public func border(edges: [Edge], color: SwiftUI.Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View 
        var view: SwiftUI.View = self
        edges.forEach  edge in
            view = view.border(edge: edge, color: color, width: width, cornerRadius: cornerRadius)
        
        return view
    

【问题讨论】:

我无法重现此内容。 你可以建立一个有forEach的函数吗?编辑:我添加了重现问题的完整代码。 删除 view = view... 并使用 view.border(...) SwiftUI 自动设置修饰符。您这样做的方式类似于每次添加修饰符时替换视图。 不起作用,它给了我这个错误:调用'border(edge:color:width:cornerRadius:)'的结果在forEach的行上是未使用的。 【参考方案1】:

我会以相反的顺序解决这个任务 - 数组的通用实现和作为具有一个元素的数组单独使用,例如:

extension SwiftUI.View 
    public func border(edge: Edge, color: SwiftUI.Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some SwiftUI.View 
        self.border(edges: [edge], color: color, width: width, cornerRadius: cornerRadius)
    

    public func border(edges: [Edge], color: SwiftUI.Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View 
        self  // generic implementation here
    

【讨论】:

不错的方法,但实际上我们只是将问题转移到了另一个函数。在这种情况下,带有数组的函数应该处理边缘的所有可能状态(例如前导;前导 + 尾随;前导 + 尾随 + 顶部;...),这是不可行的,但我写了它(大约 170 行)。然而 Xcode 现在抱怨返回类型:函数声明了一个不透明的返回类型,但它的主体中的返回语句没有匹配的底层类型(我在每个路径中返回一个 .overlay(...),它返回一个视图。我不'没有更多的想法。) 这种情况通常可以通过创建函数ViewBuilder 或在内部使用Group 来包装最顶层的条件或情况来解决。比如***.com/a/64587601/12299030 或***.com/a/60450204/12299030。 它有效,谢谢!我认为这不是最佳实践的一部分(我的意思是很长的函数体),但至少它有效:D

以上是关于如何将函数中的多个修饰符应用于 SwiftUI 中的给定视图?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI NavigationView 切换色调颜色

在 Perl/Moose 中,如何将修饰符应用于所有子类中的方法?

SwiftUI 将覆盖添加到整个屏幕

SwiftUI:数组内的修饰符

为啥修饰符顺序在 SwiftUI 中很重要? [复制]

SwiftUI-自定义修饰符