Das zweite Bild (Bild B) ist sehr breit. Um diese Frage auf einfache Weise zu erklären, habe ich das erste Bild (Bild A) mit 2 Farbtönen (gelb und rot) ausgewählt. Wenn Sie auf die rote Farbe von Bild A tippen, verhält sich die App so, als ob Bild B abgebildet wäre und das Bild B öffnet, anstatt Bild A zu öffnen A. öffnen Sie die gelbe Bild von Bild A, das Bild A richtig öffnet. < /P>
Dies geschieht, weil das Bild B breit ist und ich Image.Resizable (). Aspectratio (**. FILL **) Bilder in einer abgerundeten Rechteckform anzuzeigen. Wenn ich Image.Resizable (). Aspectratio (**. Fit **) verwende, dann funktioniert auf Verhalten einwandfrei, d. H. Wenn die rote Farbe von Bild A abgebaut wird, öffnet App das Bild A selbst, jedoch mit Aspektratio (. Anpassung), die Bilder werden nicht als abgerundetes Rechteck angezeigt. >
Code: Select all
import SwiftUI
struct Foo {
var title: String
var url: String
var image: Image?
init(title: String, url: String, image: Image? = nil) {
self.title = title
self.url = url
self.image = image
}
}
struct ContentViewA: View {
@State private var data = [
Foo(title: "Image A", url: "https://www.shutterstock.com/image-illustration/two-shades-color-background-mix-260nw-2340299851.jpg", image: nil),
Foo(title: "Image B", url: "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Sydney_Harbour_Bridge_night.jpg/800px-Sydney_Harbour_Bridge_night.jpg", image: nil)
// Foo(title: "Image B", url: "https://www.shutterstock.com/image-photo/ultra-wide-photo-mountains-river-260nw-1755037052.jpg", image: nil)
/// There are more images in the array in real code.
]
var body: some View {
ZStack {
Color.black.opacity(0.7).ignoresSafeArea()
VStack {
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .center, spacing: 10) {
ForEach(Array(data.enumerated()), id: \.offset) { index, item in
if let urlObject = URL(string: item.url) {
AsyncImage(url: urlObject,
scale: 1.0,
transaction: Transaction(animation: .spring(response: 0.5, dampingFraction: 0.65, blendDuration: 0.025)),
content: { renderPhoto(phase: $0, item: item, index: index) })
} else {
/// Note: Shows placeholder view
EmptyView()
}
}
}
.padding(.leading, 0)
.padding(.trailing, 16)
.frame(maxWidth: .infinity, minHeight: 65, maxHeight: 65, alignment: .topLeading)
}
}
.padding([.top, .bottom], 150.0)
.padding([.leading, .trailing], 50.0)
}
}
@ViewBuilder
private func renderPhoto(phase: AsyncImagePhase, item: Foo, index: Int) -> some View {
switch phase {
case .success(let image):
thumbnailView(image: image, item: item, index: index)
case .failure(let error):
thumbnailView(item: item, index: index, isFailure: true)
case .empty:
thumbnailView(item: item, index: index, isFailure: true)
@unknown default:
EmptyView()
}
}
private func thumbnailView(image: Image? = nil, item: Foo, index: Int, isFailure: Bool = false) -> some View {
VStack {
Rectangle()
.foregroundColor(.clear)
.frame(width: 72, height: 55)
.background(
VStack {
if let image = image {
image.resizable()
.aspectRatio(contentMode: .fill)
// .aspectRatio(contentMode: .fit) /// Setting aspect ratio to fit avoids the problem, but doesn't give rounded rectangle look.
.frame(width: 72, height: 55)
.disabled(false)
.clipped()
} else {
/// show error image
EmptyView()
}
}
)
.cornerRadius(8)
.padding([.top, .bottom], 10.0)
.onTapGesture {
print("%%%%% Tapped image title: \(item.title) and index is: \(index) %%%%%%")
}
}
}
}
Bilder mit Aspectratio (.fit), tippen auf das 1. Bild, öffnet das 1. Bild und tippen auf dem 2. Bild, öffnet das 2. Bild. Dies ist das Tap -Verhalten, das ich haben möchte.
Wie kann ich abgerundete rechteck aussehende Bilder haben und das richtige Bild öffnen, wenn ich auf das Bild tippen sollte, sollte nur Bild a?