Я пытаюсь изучить SwiftUI и неплохо справляюсь, но столкнулся с проблемой с размещением .zIndex/представления, с которой учебные пособия и ответы ИИ, похоже, мне не могут помочь. Огромное спасибо BenzyNeez за его вклад, и я решил одну из своих проблем с полноэкранным режимом. Дополнительные представления должны открываться в полноэкранном режиме и располагаться поверх всех остальных представлений, как и финальное изображение. Но дополнительные представления находятся поверх полноэкранного просмотра.
struct PeopleView: View {
struct Person: Identifiable {
var id: UUID = UUID()
var first: String
var last: String
var isFullScreen: Bool
var tag: Int
}
func getColor(index: Int) -> Color {
switch index {
case 1: return .blue
case 2: return .green
case 3: return .yellow
case 4: return .orange
case 5: return .purple
case 6: return .pink
default: return .gray
}
}
@Namespace private var animationNamespace
@State private var selectedPerson: Person? = nil
private let personId = UUID()
private let cardWidth: CGFloat = UIScreen.main.bounds.width / 3
@State private var fullscreen: Bool = false
var columns: [GridItem] { Array(repeating: .init(.flexible()), count: 2) }
@State private var people: [Person] = [
Person(first: "John", last: "Doe", isFullScreen: false, tag: 1),
Person(first: "Jane", last: "Doe", isFullScreen: false, tag: 2),
Person(first: "Fred", last: "Doe", isFullScreen: false, tag: 3),
Person(first: "Bill", last: "Doe", isFullScreen: false, tag: 4),
Person(first: "Jack", last: "Doe", isFullScreen: false, tag: 5),
Person(first: "Mary", last: "Doe", isFullScreen: false, tag: 6)
]
private func personView(person: Person) -> some View {
RoundedRectangle(cornerRadius: 5)
.foregroundStyle(getColor(index: person.tag))
.shadow(radius: 5)
.overlay {
Text(person.first)
}
.matchedGeometryEffect(
id: selectedPerson?.id == person.id ? personId : person.id,
in: animationNamespace,
isSource: false
)
}
private var floatingPersonViews: some View {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(people.indices, id: \.self) { index in
personView(person: people[index])
.allowsHitTesting(false)
.frame(height: 320)
}
}
}
private var cardBases: some View {
HStack {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(people.indices, id: \.self) { index in
RoundedRectangle(cornerRadius: 5)
.fill(Color.black)
.frame(width: cardWidth, height: 100)
.onTapGesture {
withAnimation(.interactiveSpring(response: 0.3, dampingFraction: 0.8, blendDuration: 0.8)) {
selectedPerson = people[index]
people[index].isFullScreen = true
fullscreen = true
}
}
.matchedGeometryEffect(
id: people[index].id,
in: animationNamespace,
isSource: true
)
.zIndex(people[index].isFullScreen ? 1 : -1)
}
}
}
.padding()
}
private var detailBase: some View {
Rectangle()
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
.opacity(0)
.matchedGeometryEffect(
id: personId,
in: animationNamespace,
isSource: true
)
}
private var detailView: some View {
VStack {
detailBase
}
.contentShape(Rectangle())
.onTapGesture {
withAnimation(.interactiveSpring(response: 0.3, dampingFraction: 0.8, blendDuration: 0.8)) {
selectedPerson?.isFullScreen = false
fullscreen = false
selectedPerson = nil
}
}
}
var body: some View {
ZStack {
cardBases//.zIndex(fullscreen ? -3 : 0)
floatingPersonViews//.zIndex(fullscreen ? -2 : 0)
detailView.zIndex(fullscreen ? 1 : -1)
}
}
}
Теперь это работает для перехода в полноэкранный режим и захвата всего представления, однако представления в LazyGrid по-прежнему видны сверху, за исключением последнего справа.
[img]https: //i.sstatic.net/26cmLTLM.png[/img]
Я попробовал установить высокий индекс .zIndex для DetailView, а также установить низкий уровень для двух других представлений с помощью полноэкранной переменной. Но, похоже, не имеет значения, какое значение установлено в .zIndex.
Я пытаюсь изучить SwiftUI и неплохо справляюсь, но столкнулся с проблемой с размещением .zIndex/представления, с которой учебные пособия и ответы ИИ, похоже, мне не могут помочь. Огромное спасибо BenzyNeez за его вклад, и я решил одну из своих проблем с полноэкранным режимом. Дополнительные представления должны открываться в полноэкранном режиме и располагаться поверх всех остальных представлений, как и финальное изображение. Но дополнительные представления находятся поверх полноэкранного просмотра. [code]struct PeopleView: View {
struct Person: Identifiable { var id: UUID = UUID() var first: String var last: String var isFullScreen: Bool var tag: Int }
func getColor(index: Int) -> Color { switch index { case 1: return .blue case 2: return .green case 3: return .yellow case 4: return .orange case 5: return .purple case 6: return .pink default: return .gray } } @Namespace private var animationNamespace
@State private var selectedPerson: Person? = nil private let personId = UUID() private let cardWidth: CGFloat = UIScreen.main.bounds.width / 3 @State private var fullscreen: Bool = false
var columns: [GridItem] { Array(repeating: .init(.flexible()), count: 2) }
var body: some View { ZStack { cardBases//.zIndex(fullscreen ? -3 : 0) floatingPersonViews//.zIndex(fullscreen ? -2 : 0) detailView.zIndex(fullscreen ? 1 : -1) } } } [/code] Теперь это работает для перехода в полноэкранный режим и захвата всего представления, однако представления в LazyGrid по-прежнему видны сверху, за исключением последнего справа. [img]https://i.sstatic.net/w58TduY8.png[/img] [img]https: //i.sstatic.net/26cmLTLM.png[/img] [img]https://i.sstatic.net/M6OfWxUp.png[/img] Я попробовал установить высокий индекс .zIndex для DetailView, а также установить низкий уровень для двух других представлений с помощью полноэкранной переменной. Но, похоже, не имеет значения, какое значение установлено в .zIndex.