SwiftUI - Button (按钮)

414 阅读2分钟

Button

1.默认 button

Button("Hello world") { 
    print("click")
}

2.自定义样式

截屏2022-12-08 下午4.43.18.png

Button {
    print("click")
} label: {
    VStack {
        Image(systemName: "square.and.arrow.up")
        Text("Share")
    }
    .padding()
    .foregroundColor(.white)
    .background(.blue)
    .cornerRadius(10)
    .shadow(color: .black.opacity(0.35), radius: 5, x: 0, y: 5)
}

3.ButtonStyle

  • plain

  • automatic

  • bordered

  • borderless

  • borderedProminent

截屏2022-12-08 下午5.00.00.png

Button("Hello World!") {
    print("click")
}
.tint(.green)
.buttonBorderShape(.capsule)
.buttonStyle(.borderless)
.controlSize(.large)  // 改变按钮大小

我们还可以通过以下两个协议自定义样式:

  • ButtonStyle :支持自定义样式

iShot_2022-12-08_17.09.27.gif

struct ShadowButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(configuration.isPressed ? .gray : .white)
            .padding()
            .background(configuration.isPressed ? .purple : .blue)
            .cornerRadius(10)
            .shadow(color: .black.opacity(0.35), radius: 5, x: 0, y: 5)
    }
}

extension ButtonStyle where Self == ShadowButtonStyle {
    static var shadow: Self {
        Self()
    }
}

VStack {
    Button("Hello") {}
    Button("World") {}
}
.buttonStyle(.shadow)
  • PrimitiveButtonStyle :支持自定义样式和交互
struct DoubleTapButtonStyle: PrimitiveButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .gesture(TapGesture(count: 2).onEnded({ _ in
                configuration.trigger()
            }))
    }
}
 
extension PrimitiveButtonStyle where Self == DoubleTapButtonStyle {
    static var doubleTap: Self {
        Self()
    }
}

Button("Double Tap") {
    print("taped")
}
.foregroundColor(.white)
.padding()
.background(.blue)
.cornerRadius(10)
.buttonStyle(.doubleTap)

EditButton

按下的时候会进入编辑状态,按钮文字变成 "Done" ,再次按下变回 "Edit",主要和 List 配合使用,通常这样调用

.navigationBarItems(trailing: EditButton())

Menu

1.字符串构建

iShot_2022-12-08_17.26.25.gif

Menu("More") {
    Button("Add") {}
    Button("Edit") {}
    Button("Delete") {}
}

2.自定义构建

iShot_2022-12-08_17.37.22.gif

Menu {
    Button(action: {}) {
        Label("Add", systemImage: "plus")
    }
    Button(action: {}) {
        Label("Edit", systemImage: "pencil")
    }
    Button(action: {}) {
        Label("Delete", systemImage: "minus.circle")
    }
} label: {
    Text("More")
    Image(systemName: "ellipsis")
}

3.自定义 MenuStyle

截屏2022-12-08 下午5.46.13.png

struct BorderMenuStyle: MenuStyle {
    func makeBody(configuration: Configuration) -> some View {
        Menu(configuration)
            .foregroundColor(.blue)
            .padding(3)
            .border(.blue, width: 2)
    }
}

extension MenuStyle where Self == BorderMenuStyle
{
    static var border: Self {  Self() }
}

Menu("More") {
    Button("Add") {}
    Button("Edit") {}
    Button("Delete") {}
}
.menuStyle(.border)

toolbar

用于构建工具栏,它可以放置在不同的位置,比如导航栏、键盘上、视图底部等。

iShot_2022-12-08_17.58.24.gif

struct ToolbarView: View {
  @State private var text = ""
  @State private var bold = false
  @State private var textColor: Color = .primary
  @State private var fontSize: CGFloat = 18

  var font: Font {
    .system(size: fontSize, weight: bold ? .bold : .regular)
  }

  var body: some View {
    TextEditor(text: $text)
      .font(font)
      .foregroundColor(textColor
      .frame(height: 200)
      .overlay(
        RoundedRectangle(cornerRadius: 10)
          .stroke(.blue, lineWidth: 1)
      )
      .padding(.horizontal)
      .toolbar {
        ToolbarItemGroup(placement: .navigationBarTrailing) {
          ColorPicker("", selection: $textColor)  // 颜色拾取器
          Toggle(isOn: $bold) {   // toggle 开关
            Image(systemName: "bold")
          }
        }
       
        ToolbarItem(placement: .keyboard) {
          HStack {
            Spacer()
            Button("确定") {
              UIApplication.shared.sendAction(
                #selector(UIResponder.resignFirstResponder),
                to: nil, from: nil, for: nil)  // 收起键盘
            }
          }
        }

        ToolbarItem(placement: .bottomBar) {
          Slider(value: $fontSize, in: 12...24) {   // 滑动条
            Text("Font Size: \(fontSize)")
          } minimumValueLabel: {
            Text("A").font(.system(size: 12))
          } maximumValueLabel: {
            Text("A").font(.system(size: 24))
          }
        }
      }
  }
}

NavigationView {
    ToolbarView()
}

Link

Link("网易", destination: URL(string: "https://www.163.com")!)

Link 可以用来打开网页链接,如果通用链接(Universal Link)支持,会跳转到对应的 App 页面