|
import SwiftUI |
|
|
|
extension Color { |
|
static var redmondBackground = Color(white: 0.78) |
|
static var redmondShadow = Color(white: 0.55) |
|
} |
|
|
|
extension Font { |
|
static var redmondLabel = Font(UIFont(name: "MicrosoftSansSerif", size: UIFont.labelFontSize)!) |
|
} |
|
|
|
struct RedmondButtonStyle: ButtonStyle { |
|
@State var lineWidth: CGFloat = 2 |
|
|
|
func makeBody(configuration: Self.Configuration) -> some View { |
|
let offset = configuration.isPressed ? lineWidth : 0 |
|
return configuration.label |
|
.font(.redmondLabel) |
|
.offset(x: offset, y: offset).animation(nil) |
|
.background( |
|
ZStack { |
|
Corner(style: configuration.isPressed ? .topLeft : .bottomRight).stroke(Color.redmondShadow, lineWidth: lineWidth).padding(lineWidth) |
|
Corner(style: configuration.isPressed ? .bottomRight : .topLeft).stroke(Color.white, lineWidth: lineWidth) |
|
Corner(style: configuration.isPressed ? .topLeft : .bottomRight).stroke(Color.black, lineWidth: lineWidth) |
|
} |
|
.animation(nil) |
|
) |
|
} |
|
} |
|
|
|
struct Corner: Shape { |
|
enum Style { case topLeft, bottomRight } |
|
|
|
@State var style: Style |
|
|
|
func path(in rect: CGRect) -> Path { |
|
Path { path in |
|
path.move(to: CGPoint(x: 0, y: rect.size.height)) |
|
path.addLine(to: style == .topLeft ? .zero : CGPoint(x: rect.size.width, y: rect.size.height)) |
|
path.addLine(to: CGPoint(x: rect.size.width, y: 0)) |
|
} |
|
} |
|
} |
|
|
|
struct DemoView: View { |
|
private func button(text: String, action: @escaping () -> ()) -> some View { |
|
button(content: Text(text).frame(width: 90, height: 35), action: action) |
|
} |
|
|
|
private func button(systemImageName: String, action: @escaping () -> ()) -> some View { |
|
button(content: |
|
Image(systemName: systemImageName) |
|
.resizable() |
|
.aspectRatio(contentMode: .fit) |
|
.frame(width: 25, height: 25) |
|
.padding(8), |
|
action: action) |
|
} |
|
|
|
private func button<T: View>(content: T, action: @escaping () -> ()) -> some View { |
|
Button(action: action) { |
|
content |
|
}.buttonStyle(RedmondButtonStyle()) |
|
} |
|
|
|
var body: some View { |
|
VStack(alignment: .leading, spacing: 20) { |
|
HStack { |
|
button(systemImageName: "doc.text") { print("doc") } |
|
button(systemImageName: "folder") {} |
|
button(systemImageName: "calendar") {} |
|
button(systemImageName: "person") {} |
|
button(systemImageName: "trash") {} |
|
Spacer() |
|
} |
|
|
|
HStack { |
|
button(text: "Cancel") {} |
|
button(text: "OK") { print("ok") } |
|
Spacer() |
|
} |
|
|
|
Spacer() |
|
} |
|
.padding() |
|
.background(Color.redmondBackground) |
|
} |
|
} |
|
|
|
struct DemoView_Previews: PreviewProvider { |
|
static var previews: some View { |
|
DemoView() |
|
} |
|
} |
Not working.