我可以在 SwiftUI 中以编程方式生成一系列视图吗?

Can I generate a sequence of Views programatically in SwiftUI?

提问人:Richard Kirk 提问时间:10/1/2022 最后编辑:Richard Kirk 更新时间:10/1/2022 访问量:223

问:

这是一个对我有用的代码片段......

    VStack(spacing: pad/2) { 
        getRgbColor(i:0)
            .onTapGesture { editColor(i:0) }
            .frame(width: pad, height: pad)
            .border(.black.opacity(0.5), width: 1)
                
        getRgbColor(i:1)
            .onTapGesture { editColor(i:1) }
            .frame(width: pad, height: pad)
            .border(.black.opacity(0.5), width: 1)
 
        getRgbColor(i:2)
            .onTapGesture { editColor(i:2) }
            .frame(width: pad, height: pad)
            .border(.black.opacity(0.5), width: 1)
    }

原版有更多的条目。它起作用了,但你可以看到它是如何重复的。我可能想制作一组看起来像麦克白目标的 6x4 补丁,所以我想知道是否有更好的方法不会重复那么多。我尝试将呼叫移动到呼叫中。getRgbColor()

    func getRgbColor(i:Int) -> SwiftUI.Color {
        return SwiftUI.Color(red:   R + rgbDel[i][0] * step,
                             green: G + rgbDel[i][1] * step,
                             blue:  B + rgbDel[i][2] * step)
            .onTapGesture { editColor(i:0) }
            .frame(width: pad, height: pad)
            .border(.black.opacity(0.5), width: 1) as! Color 
    }

这编译了,但在我运行它时给出了一个 SIGABRT......

无法强制转换类型的值 'SwiftUI.ModifiedContent<SwiftUI.ModifiedContent<SwiftUI.ModifiedContent<SwiftUI.Color, SwiftUI.AddGestureModifier<SwiftUI._EndedGesture<SwiftUI.TapGesture>>>, SwiftUI._FrameLayout>, SwiftUI._OverlayModifier<SwiftUI._ShapeView<SwiftUI._StrokedShape<SwiftUI.Rectangle._Inset>, SwiftUI.Color>>>' (0x109735e90) 更改为 'SwiftUI.Color' (0x1ec3b9eb8)。 2022-10-01 12:38:49.468445+0100 ByEye[2810:493288] 无法投射 类型的值 'SwiftUI.ModifiedContent<SwiftUI.ModifiedContent<SwiftUI.ModifiedContent<SwiftUI.Color, SwiftUI.AddGestureModifier<SwiftUI._EndedGesture<SwiftUI.TapGesture>>>, SwiftUI._FrameLayout>, SwiftUI._OverlayModifier<SwiftUI._ShapeView<SwiftUI._StrokedShape<SwiftUI.Rectangle._Inset>, SwiftUI.Color>>>' (0x109735e90) 更改为 'SwiftUI.Color' (0x1ec3b9eb8)。

有没有巧妙的解决方案?

是的,有。我没有想到调用修饰符会改变底层类型,因为我写的大部分内容都是用 cpp 编写的,这是不可想象的。在第一条评论之后,我编写并重命名了 getRgbColor() 函数......

    func rgbButton(i:Int) -> some View {
        return SwiftUI.Color(red:   R + rgbDel[i][0] * step,
                             green: G + rgbDel[i][1] * step,
                             blue:  B + rgbDel[i][2] * step)
                .onTapGesture { editColor(i:i) }
                .frame(width: pad, height: pad)
    }
iOS SwiftUI 关闭

评论


答:

1赞 Gavin Morrow 10/1/2022 #1

SwiftUI 中的修饰符实际上不会修改视图。取而代之的是,它们会创建一个新视图(例如),并更改/应用属性。ModifiedContent

每当我们将修饰符应用于 SwiftUI 视图时,我们实际上都会创建一个应用该更改的新视图——我们不仅仅是就地修改现有视图。

- 使用 Swift 进行黑客攻击

因此,当您将所有修饰符添加到 Color 时,您正在使其成为不同类型的视图。这就是失败的原因。as! Color

要解决此问题,您可以为 rgb 颜色制作一个视图。

struct RgbColor: View {
    let i: Int
    // Add any other info the view needs as constants

    var body: some View {
       // ...
    }
}

要使用它,请执行以下操作:

RgbColor(i: 1, /* other parameters */)

我希望这会有所帮助!

评论

0赞 Richard Kirk 10/1/2022
在此评论之后,将我的解决方案附加到我的原始问题中。非常感谢。