In my SwiftUI ContentView, I have a media view with an image or video that should have rounded corners. However, the media often loses its rounded corners at the bottom and appears cut off. I’ve tried multiple adjustments to the layout without success.
I suspect it may have something to do with layering or how the caption section affects the media display. Here is a screenshot illustrating the issue:
I’ve tried fixing it using ZStack and other layout adjustments, but the problem persists. Here is the relevant portion of my code:
import SwiftUI
import AVKit
// MARK: - MediaView
struct MediaView: View {
let fileName: String
let profilePicFileName: String
let username: String
var body: some View {
VStack {
HStack {
if let profilePicUrl = MediaStorageManager.shared.loadMedia(fileName: profilePicFileName) {
AsyncImage(url: profilePicUrl) { image in
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 30, height: 30)
.clipShape(Circle())
} placeholder: {
ProgressView()
.frame(width: 15, height: 15)
}
} else {
Text("N/A")
.font(.system(size: 10))
.frame(width: 15, height: 15)
}
Text(username)
.foregroundColor(.white)
Spacer()
}
.padding([.horizontal, .top], 20)
// Main media display section
ZStack {
Group {
if fileName.contains(".mp4") {
if let videoURL = MediaStorageManager.shared.loadMedia(fileName: fileName) {
VideoPlayer(player: AVPlayer(url: videoURL))
.aspectRatio(9 / 16, contentMode: .fill)
.frame(width: 360, height: 590)
.cornerRadius(15)
.clipped()
} else {
Text("Video file not found")
}
} else {
if let imageURL = MediaStorageManager.shared.loadMedia(fileName: fileName) {
AsyncImage(url: imageURL) { image in
image
.resizable()
.scaledToFill()
.frame(width: 360, height: 590)
.cornerRadius(15)
.clipped()
} placeholder: {
ProgressView()
}
} else {
Text("Image file not found")
}
}
}
}
}
.padding(.top, 20)
}
}
// MARK: - ContentView
struct ContentView: View {
@State private var refreshID = UUID() // Used to force-refresh the TabView
var body: some View {
NavigationView {
ScrollView { // Make the whole UI scrollable
VStack {
TabView {
ForEach(viewModel.mediaUrls, id: .self) { fileName in
MediaView(fileName: fileName,
profilePicFileName: viewModel.profilePicUrl, // Pass profile picture filename directly
username: viewModel.username)
}
}
.tabViewStyle(PageTabViewStyle())
.frame(height: 600)
.id(refreshID)
interactionDetails
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
pasteButton
}
}
.onChange(of: viewModel.mediaUrls) { oldValue, newValue in
refreshID = UUID() // Force TabView update
print("Old URLs: (oldValue)")
print("New URLs: (newValue)")
}
}
}
}
private var pasteButton: some View {
Button(action: {
viewModel.handlePasteButtonAction()
}) {
Image(systemName: "plus.circle.fill")
}
.tint(.green)
}
private var interactionDetails: some View {
VStack {
HStack {
Image(systemName: "heart")
Text("(viewModel.likeCount)")
Image(systemName: "bubble.right")
Text("(viewModel.commentCount)")
Spacer()
}
.padding(.horizontal)
.padding(.top, 5)
Divider()
Text(viewModel.captionText)
.font(.system(size: 12))
.foregroundColor(.white)
.lineLimit(nil)
.padding(.all, 10)
}
.frame(height: 120)
.background(Color.gray)
.frame(width: 360)
.cornerRadius(15)
.padding(.top, 20)
}
}
How can I maintain the rounded corners on my media while keeping the caption section directly below it without causing clipping or overlap?