我目前正在开发自己的 Apple TV 应用程序。到目前为止,一切进展顺利,但现在,我陷入了类别或选择菜单的设计。
这是现在的屏幕截图: 请看这里的截图
现在特意添加了绿色和边框,以便我可以看到什么在哪里。我的实际目标是删除灰色条(或者这是“主条”?)。粉色条及其边框只是设计元素,可以根据需要删除。我希望它看起来更“原始”,像这样: 请看这里的截图
这是代码:
struct SettingsCategoryView: View {
let title: String
let isSelected: Bool
var body: some View {
HStack {
Text(title)
.foregroundColor(isSelected ? .black : .white)
.font(.system(size: 22, weight: .regular))
.padding(.leading, 20)
Spacer()
Image(systemName: "chevron.right")
.foregroundColor(isSelected ? .black : .gray)
.padding(.trailing, 20)
}
.frame(height: 50) // Einheitliche Höhe für die Kategorien
.background(Color.pink) // Innerer Hintergrund auf pink gesetzt
.cornerRadius(10) // Abrundung direkt auf den Hintergrund anwenden
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.green, lineWidth: 3) // Äußerer Rahmen auf grün gesetzt
)
.padding(.horizontal, 0) // Entferne äußere Ränder
.background(Color.clear) // Entferne alle anderen Hintergründe
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}
我已经调整了代码,但还是不太对劲。当未选择某个类别时,它会显示为黑色而不是灰色,就像原始设计中那样。 请看这里的截图
这是代码:
import SwiftUI
struct SettingsView: View {
@State private var selectedCategory: String?
var body: some View {
NavigationStack {
ZStack {
Color.black
.edgesIgnoringSafeArea(.all)
VStack(spacing: 0) {
// Überschrift oben in der Mitte
Text("Einstellungen")
.font(.system(size: 40, weight: .semibold))
.foregroundColor(.white)
.padding(.top, 30)
HStack {
// Linke Seite mit Logo
VStack {
Spacer()
Image(systemName: "applelogo")
.resizable()
.scaledToFit()
.frame(width: 120, height: 120)
.foregroundColor(.white)
Spacer()
}
.frame(width: UIScreen.main.bounds.width * 0.4)
// Rechte Seite mit Kategorien
VStack(spacing: 15) {
ForEach(categories, id: \.self) { category in
NavigationLink(
value: category,
label: {
SettingsCategoryView(
title: category,
isSelected: selectedCategory == category
)
}
)
.buttonStyle(PlainButtonStyle())
}
}
.frame(width: UIScreen.main.bounds.width * 0.5)
}
}
}
.navigationDestination(for: String.self) { value in
Text("\(value)-Ansicht")
.font(.title)
.foregroundColor(.white)
.navigationTitle(value)
}
}
}
private var categories: [String] {
["Allgemein", "Benutzer:innen und Accounts", "Video und Audio", "Bildschirmschoner", "AirPlay und HomeKit", "Fernbedienungen und Geräte", "Apps", "Netzwerk", "System", "Entwickler"]
}
}
struct SettingsCategoryView: View {
let title: String
let isSelected: Bool
var body: some View {
HStack {
Text(title)
.foregroundColor(.white)
.font(.system(size: 22, weight: .medium))
.padding(.leading, 20)
Spacer()
Image(systemName: "chevron.right")
.foregroundColor(.gray)
.padding(.trailing, 20)
}
.frame(height: 50) // Einheitliche Höhe für die Kategorien
.background(isSelected ? Color.gray.opacity(0.3) : Color.clear) // Hervorhebung des ausgewählten Elements
.cornerRadius(8) // Abgerundete Ecken
.scaleEffect(isSelected ? 1.05 : 1.0) // Fokus-Animation
.animation(.easeInOut, value: isSelected)
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}
我就是做不到。现在我可以看到未选择的区域,但是那个烦人的大灰色条又回来了。 请看这里的截图
这是代码:
import SwiftUI
struct SettingsView: View {
@State private var selectedCategory: String?
var body: some View {
NavigationStack {
ZStack {
Color.black
.edgesIgnoringSafeArea(.all)
VStack(spacing: 0) {
// Überschrift oben in der Mitte
Text("Einstellungen")
.font(.system(size: 40, weight: .semibold))
.foregroundColor(.white)
.padding(.top, 30)
HStack {
// Linke Seite mit Logo
VStack {
Spacer()
Image(systemName: "applelogo")
.resizable()
.scaledToFit()
.frame(width: 120, height: 120)
.foregroundColor(.white)
Spacer()
}
.frame(width: UIScreen.main.bounds.width * 0.4)
// Rechte Seite mit Kategorien
VStack(spacing: 15) {
ForEach(categories, id: \.self) { category in
NavigationLink(
value: category,
label: {
SettingsCategoryView(
title: category,
isSelected: selectedCategory == category
)
}
)
.buttonStyle(PlainButtonStyle())
}
}
.frame(width: UIScreen.main.bounds.width * 0.5)
}
}
}
.navigationDestination(for: String.self) { value in
Text("\(value)-Ansicht")
.font(.title)
.foregroundColor(.white)
.navigationTitle(value)
}
}
}
private var categories: [String] {
["Allgemein", "Benutzer:innen und Accounts", "Video und Audio", "Bildschirmschoner", "AirPlay und HomeKit", "Fernbedienungen und Geräte", "Apps", "Netzwerk", "System", "Entwickler"]
}
}
struct SettingsCategoryView: View {
let title: String
let isSelected: Bool
var body: some View {
HStack {
Text(title)
.foregroundColor(.white)
.font(.system(size: 22, weight: .medium))
.padding(.leading, 20)
Spacer()
Image(systemName: "chevron.right")
.foregroundColor(.gray)
.padding(.trailing, 20)
}
.frame(height: 50) // Einheitliche Höhe für die Kategorien
.background(isSelected ? Color.gray.opacity(0.3) : Color.gray.opacity(0.15)) // Hintergrundfarbe für ausgewählte und nicht ausgewählte Kategorien
.cornerRadius(8) // Abgerundete Ecken
.scaleEffect(isSelected ? 1.05 : 1.0) // Fokus-Animation
.animation(.easeInOut, value: isSelected)
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView()
}
}
我希望它看起来像第二个屏幕截图中的那样。我已经多次调整代码,但始终不起作用。事实上,我更喜欢最后一张截图中的样子,但大的灰色条不会消失。
您可以通过三个小更改让它更像您的目标设计:
selectedCategory
更改为 FocusState
变量:@FocusState private var selectedCategory: String?
为
.focused
添加 NavigationLink
修饰符,以便当焦点更改时 selectedCategory
得到更新。
将
.borderless
作为按钮样式应用于导航链接,而不是 PlainButtonStyle
:
NavigationLink(
// ...
)
.focused($selectedCategory, equals: category)
.buttonStyle(.borderless)
这些更改后的效果如下:
您可能会注意到,在上面的 gif 中,所选行的右侧有一个选择标记。这好像是带有按钮样式的东西
.borderless
。如果你想摆脱这个,你可以定义自己的自定义按钮样式并使用它来代替 .borderless
:
struct BasicButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
}
}
.buttonStyle(BasicButtonStyle())
顺便说一句,您在某些地方使用了已弃用的代码:
修饰符
.edgesIgnoringSafeArea(.all)
已弃用,请使用 .ignoresSafeArea()
代替。
修饰符
.foregroundColor
已弃用,请使用 .foregroundStyle
代替。
修饰符
.cornerRadius
已弃用。在背景中显示圆角矩形:
.background {
RoundedRectangle(cornerRadius: 8)
.fill(.gray.opacity(isSelected ? 0.3 : 0.15))
}
// .background(isSelected ? Color.gray.opacity(0.3) : Color.clear) // Hervorhebung des ausgewählten Elements
// .cornerRadius(8) // Abgerundete Ecken
UIScreen.main
已弃用。一种替换方法是将父视图包装在 GeometryReader
中。 GeometryReader
将其内容与左上角对齐。如果内容尚未扩展以使用所有可用空间,则可以通过设置 maxWidth 和 maxHeight 的框架将其与屏幕中心对齐:var body: some View {
GeometryReader { proxy in
let screenWidth = proxy.size.width
NavigationStack {
// ...
// Linke Seite mit Logo
VStack {
// ...
}
.frame(width: screenWidth * 0.4)
// Rechte Seite mit Kategorien
VStack(spacing: 15) {
// ...
}
.frame(width: screenWidth * 0.5)
}
}
}
.navigationDestination(for: String.self) { value in
Text("\(value)-Ansicht")
.font(.title)
.foregroundColor(.white)
.navigationTitle(value)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}