blog icon indicating copy to clipboard operation
blog copied to clipboard

SwiftUI组件-按钮组件

Open diamont1001 opened this issue 2 years ago • 0 comments

组件预览

image

代码

import SwiftUI

struct TextButton: View {
    let title: String
    let icon: String
    let color: Color
    let bold: Bool
    let radius: CGFloat
    let fill: Bool // 填充
    let expand: Bool // 是否宽度100%
    let exBorder: Bool // 是否要外框
    
    private var paddingVertical: CGFloat {
        exBorder ? 12 : (fill ? 15 : 14)
    }
    
    init(_ title: String, icon: String = "", color: Color = .orange, bold: Bool = false, radius: CGFloat = 5, fill: Bool = false, expand: Bool = false, exBorder: Bool = false) {
        self.title = title
        self.icon = icon
        self.color = color
        self.bold = bold
        self.radius = radius
        self.fill = fill
        self.expand = expand
        self.exBorder = exBorder
    }
    
    var body: some View {
        HStack {
            if icon != "" {
                Image(systemName: icon)
            }
            Text(NSLocalizedString(self.title, comment: ""))
                .if(bold) { view in
                    view
                        .bold()
                }
        }
            .if(expand) { view in
                view
                    .frame(maxWidth: .infinity)
            }
            .if(fill) { view in
                view
                    .foregroundColor(.white)
                    .padding([.leading, .trailing], 30)
                    .padding([.top, .bottom], paddingVertical)
                    .background(color)
                    .cornerRadius(radius)
            }
            .if(!fill) { view in
                view
                    .foregroundColor(color)
                    .padding([.leading, .trailing], 30)
                    .padding([.top, .bottom], paddingVertical)
                    .overlay(
                        RoundedRectangle(cornerRadius: radius)
                            .stroke(color, lineWidth: 1)
                    )
            }
            .if(exBorder) { view in
                view
                    .padding(4)
                    .overlay(
                        RoundedRectangle(cornerRadius: radius)
                            .stroke(self.color.opacity(0.8), lineWidth: 2)
                    )
            }
    }
}

struct TextButton_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            TextButton("TextButton")
            TextButton("Copy", icon: "square.on.square")
            TextButton("TextButton", fill: true)
            TextButton("TextButton", radius: 40)
            TextButton("TextButton", radius: 40, fill: true)
            TextButton("TextButton", radius: 40, fill: true, exBorder: true)
            TextButton("TextButton", fill: true, expand: true)
                .padding([.leading, .trailing])
            TextButton("TextButton", fill: true, expand: true, exBorder: true)
                .padding([.leading, .trailing])
            TextButton("TextButton", radius: 40, fill: true, expand: true, exBorder: true)
                .padding([.leading, .trailing])
        }
    }
}

extension View {
    // 支持 View{}.if() 的写法
    /* 例子
     Text("Hello")
         .if(true) { view in
             view
                 .frame(maxWidth: .infinity)
         }
     */
    @ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View {
        if condition {
            transform(self)
        } else {
            self
        }
    }
}

diamont1001 avatar Jul 09 '22 04:07 diamont1001