如何对各种形状使用同一组修饰符 [英] How to use same set of modifiers for various shapes

查看:37
本文介绍了如何对各种形状使用同一组修饰符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为我学习 SwiftUI 项目的一部分,我做了一些形状旋转,下面有代码.我想知道如何避免为每个形状使用相同的三行修饰符.

As a part of my learning SwiftUI project I do some shape rotations and I have code below. I'm wondering how to avoid of same three lines of modifiers for each shape.

func getShape(shape: Int, i: Int) -> AnyView {
    
    switch shape {
    case 0:
        return AnyView(Rectangle()
                        .stroke(colors[Int(shapeColor)])
                        .frame(width: CGFloat(shapeWidth), height: CGFloat(shapeHeight))
                        .rotationEffect(Angle(degrees: Double(i) * Double(angleStep))))
    case 1:
        return AnyView(Capsule()
                        .stroke(colors[Int(shapeColor)])
                        .frame(width: CGFloat(shapeWidth), height: CGFloat(shapeHeight))
                        .rotationEffect(Angle(degrees: Double(i) * Double(angleStep))))
    case 2:
        return AnyView(Ellipse()
                        .stroke(colors[Int(shapeColor)])
                        .frame(width: CGFloat(shapeWidth), height: CGFloat(shapeHeight))
                        .rotationEffect(Angle(degrees: Double(i) * Double(angleStep))))
    default:
        return AnyView(Rectangle()
                        .stroke(colors[Int(shapeColor)])
                        .frame(width: CGFloat(shapeWidth), height: CGFloat(shapeHeight))
                        .rotationEffect(Angle(degrees: Double(i) * Double(angleStep))))
        
    }
}

推荐答案

您可以通过使用辅助函数和扩展来抽象掉一些重复.

You can abstract some of the repetition away by using helper functions and extensions.

  1. 在下面的简化示例中,我使用 @ViewBuilder 来清理我们返回的代码.无需使用AnyView,它使代码更易于阅读.

  1. In the simplified example below I use a @ViewBuilder to clean up the code that we are returning. There is no need to use AnyView and it makes the code much easier to read.

如果我们能返回 some Shape 那就太好了,但是这是目前不可能并导致错误.这就是中风的原因getShape 中的每个 Shape 的值都必须重复函数,否则我们可以在 Shape 上进行扩展而不是 View.

It would be great if we could return some Shape however this is not currently possible and results in errors. This is why the stroke value has to be repeated for each Shape in the getShape function, otherwise we could have made the extension on Shape instead of View.

我在 View 上创建了一个扩展,它允许我们将修饰符组合成一个函数,使其更具可读性和更易于使用.虽然老实说这部分是可选的,你可以使用你的两个修饰符 framerotationEffect.

I create an extension on View that allows us to combine the modifiers into one function making it more readable and easier to use. Though honestly this part is optional and you could use your two modifiers frame and rotationEffect.

@ViewBuilder getShape(shape:index:) 返回您选择的形状及其所选颜色,然后由函数 createShape(shape:index:) 在其中添加我们创建的自定义修饰符作为 View 的扩展.

The @ViewBuilder getShape(shape:index:) returns the the shape you have picked with its chosen color, this is then used by the function createShape(shape:index:) where you add the custom modifier that we created as an extension on View.

最后我们创建了我们的形状

Finally we create our shape

这应该给你一个起点.

struct ShapeView: View {

    @ViewBuilder // 1
    func getShape(shape: Int, i: Int) -> some View {
        switch shape {
        case 0:
            Rectangle().stroke(Color.red)
        case 1:
            Capsule().stroke(Color.red)
        case 2:
            Ellipse().stroke(Color.red)
        default:
            Rectangle().stroke(Color.red)
        }
    }

    func createShape(shape: Int, index: Int) -> some View { // 3
        getShape(shape: shape, i: index)
            .myModifier(width: 200, height: 100, index: index, angleStep: 30)
    }

    var body: some View {
        createShape(shape: 2, index: 1) // 4
    }
}
  
// 2
extension View {
    func myModifier(width: CGFloat, height: CGFloat, index: Int, angleStep: Double) -> some View {
        self
            .frame(width: width, height: height)
            .rotationEffect(Angle(degrees: Double(index) * Double(angleStep)))
    }
}

struct ShapeView_Previews: PreviewProvider {
    static var previews: some View {
        ShapeView()
    }
}


很遗憾我们不能从 @ViewBuilder 返回 some Shape 或者如果存在 @ShapeBuilder 因为这意味着我们不必为每个形状单独添加笔画,因为 View 不能有笔画.


It is such a shame that we cannot return some Shape from the @ViewBuilder or if there existed a @ShapeBuilder as this would mean that we wouldn't have to add the stroke to each shape individually, as a View cannot have a stroke.

这篇关于如何对各种形状使用同一组修饰符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆