应用程序中存在一些按钮,例如TextEdit,其中相邻按钮的侧面连接在一起。有谁知道我如何复制这个视觉效果?我正在 MacOS 上使用 SwiftUI,非常感谢 MacOS 10 和 11 的答案。
我认为这在 SwiftUI 中是不可能的,除非你想从头开始构建它。您在 TextEdit 中看到的是一个允许多项选择的 NSSegmentedControl:https://developer.apple.com/design/ human-interface-guidelines/macos/selectors/segmented-controls/
在 SwiftUI 中,分段控件是使用 Picker 制作的,它不允许多选。最好的选择是将 NSSegmentedControl 包装在 NSHostingView 中。
使用 SwiftUI 复制这些按钮并不是那么困难。 这是一个非常
basic approach
,根据你的喜好调整颜色、角等:
import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
var body: some View {
TextFormats()
}
}
struct GrayButtonStyle: ButtonStyle {
let w: CGFloat
let h: CGFloat
init(w: CGFloat, h: CGFloat) {
self.w = w
self.h = h
}
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(Color.white)
.frame(width: w, height: h)
.padding(5)
.background(Color(UIColor.systemGray4))
.overlay(Rectangle().strokeBorder(Color.gray, lineWidth: 1))
}
}
struct TextFormats: View {
let sx = CGFloat(20)
let color = Color.black
@State var bold = false
@State var italic = false
@State var underline = false
var body: some View {
HStack (spacing: 0) {
Group {
Button(action: { bold.toggle() }) {
Image(systemName: "bold").resizable().frame(width: sx, height: sx)
.foregroundColor(bold ? .blue : color)
}
Button(action: { italic.toggle() }) {
Image(systemName: "italic").resizable().frame(width: sx, height: sx)
.foregroundColor(italic ? .blue : color)
}
Button(action: { underline.toggle() }) {
Image(systemName: "underline").resizable().frame(width: sx, height: sx)
.foregroundColor(underline ? .blue : color)
}
}.buttonStyle(GrayButtonStyle(w: sx+5, h: sx+5))
}.padding(1)
.overlay(RoundedRectangle(cornerRadius: 5).strokeBorder(.white, lineWidth: 2))
.clipped(antialiased: true)
}
}
从 iOS 15 开始,Apple 添加了
ControlGroup
视图。您可以使用它来向 SwiftUI 指示它的子级具有某种关系并且应该一起渲染。
这是一个简单的例子:
struct TextEditingView: View {
@State private var fullText: String = "This is some editable text..."
var body: some View {
ControlGroup {
TextEditor(text: $fullText)
.foregroundColor(Color.gray)
.font(.custom("HelveticaNeue", size: 13))
.lineSpacing(5)
Button("First") { }
Button("Second") { }
}
.padding()
}
}