I’ve a ProfileView that presents a modal referred to as CoinPopUp when a button is tapped. The CoinPopUp comprises a picture that I need to prolong above the modal’s prime boundary, creating an overlapping impact. Nevertheless, I can not seem to get the picture to increase outdoors the modal’s boundaries.
In UIKit, this may need been achieved utilizing the .clipsToBounds(false) methodology, which permits views to increase past their mum or dad view’s boundaries. Nevertheless, I need to preserve the modal presentation model offered by SwiftUI, which incorporates the flexibility to attenuate and prolong to full display screen if wanted.
Right here’s the related code:
ProfileView
import SwiftUI
struct ProfileView: View {
@ObservedObject var consumer: Person
@State non-public var showPopUp = false
var physique: some View {
NavigationView {
VStack {
// Prime bar
HStack {
Picture(systemName: "trophy.fill")
.foregroundColor(.yellow)
Spacer()
Textual content("4:45")
Spacer()
HStack {
Picture(systemName: "circle.fill")
.foregroundColor(.yellow)
Button("291") {
showPopUp = true
}
.sheet(isPresented: $showPopUp) {
CoinPopUp(isPresented: $showPopUp)
.presentationDetents([.medium, .large])
.background(Colour.clear)
}
}
}
.padding()
Spacer()
// Profile Image
VStack {
Circle()
.body(width: 100, peak: 100)
.foregroundColor(.grey)
.overlay(
Picture(systemName: "individual.fill")
.resizable()
.scaledToFit()
.body(width: 50, peak: 50)
.foregroundColor(.white)
)
Textual content(consumer.identify)
.font(.title)
.fontWeight(.daring)
HStack {
NavigationLink(vacation spot: EditProfileView(consumer: consumer)) {
GreyButton(buttonText: "edit profile")
}
NavigationLink(vacation spot: EditProfileView(consumer: consumer)) {
Picture(systemName: "sq..and.arrow.up")
.foregroundColor(.white)
.padding()
.background(Colour.crimson)
.clipShape(Circle())
}
}
.padding(.prime, 8)
// About Part
HStack {
VStack {
Textual content("Followers")
.font(.subheadline)
Textual content("5")
.font(.title2)
.fontWeight(.daring)
}
VStack {
Textual content("Streak")
.font(.subheadline)
HStack {
Textual content("2")
.font(.title2)
.fontWeight(.daring)
Picture(systemName: "flame.fill")
.foregroundColor(.crimson)
}
}
}
.padding(.prime, 16)
}
Spacer()
}
}
}
}
CoinPopUp
import SwiftUI
struct CoinPopUp: View {
@Binding var isPresented: Bool
@State non-public var selectedCoin: Int? = nil
@State non-public var offset: CGFloat = 0
let columns: [GridItem] = Array(repeating: .init(.versatile(), spacing: 10), rely: 3)
var physique: some View {
GeometryReader { geometry in
ZStack {
VStack(spacing: 20) {
Spacer().body(peak: 40)
Textual content("get cash")
.font(.title2)
.fontWeight(.daring)
LazyVGrid(columns: columns, spacing: 10) {
CoinOptionView(cash: 65, worth: "$0.99", isSelected: selectedCoin == 65)
.onTapGesture { selectedCoin = 65 }
CoinOptionView(cash: 330, worth: "$4.99", isSelected: selectedCoin == 330)
.onTapGesture { selectedCoin = 330 }
CoinOptionView(cash: 660, worth: "$9.99", isSelected: selectedCoin == 660)
.onTapGesture { selectedCoin = 660 }
CoinOptionView(cash: 1320, worth: "$19.99", isSelected: selectedCoin == 1320)
.onTapGesture { selectedCoin = 1320 }
CoinOptionView(cash: 3300, worth: "$49.99", isSelected: selectedCoin == 3300)
.onTapGesture { selectedCoin = 3300 }
CoinOptionView(cash: 6600, worth: "$99.99", isSelected: selectedCoin == 6600)
.onTapGesture { selectedCoin = 6600 }
}
Button(motion: {
// Implement coin buy
}) {
Textual content("get 330 cash")
.foregroundColor(.white)
.fontWeight(.daring)
.padding()
.body(maxWidth: .infinity)
.background(Colour.pink)
.cornerRadius(25)
}
Button(motion: {
// Implement video advert playback
}) {
Textual content("faucet without cost cash")
.foregroundColor(.black)
.fontWeight(.daring)
}
}
.padding()
.background(Colour.white)
.cornerRadius(20)
.offset(y: offset)
.gesture(
DragGesture()
.onChanged { worth in
let newOffset = worth.translation.peak
offset = newOffset > 0 ? 0 : newOffset
}
.onEnded { worth in
if worth.translation.peak < -50 {
withAnimation {
offset = -geometry.measurement.peak + 100
}
} else {
withAnimation {
offset = 0
}
}
}
)
// Picture overlay to increase past the modal boundaries
VStack {
Picture(systemName: "circle.fill")
.foregroundColor(.yellow)
.overlay(
Picture(systemName: "bubble.left.fill")
.foregroundColor(.white)
.font(.system(measurement: 24))
)
.font(.system(measurement: 60))
.offset(y: -geometry.measurement.peak / 2.5)
.opacity(1 - min(1, offset * 0.02 ))
Spacer()
}
}
}
.body(maxWidth: .infinity, maxHeight: .infinity) // Make sure the view covers the display screen
.background(Colour.black.opacity(0.5)) // Background dim impact
.edgesIgnoringSafeArea(.all) // Prolong the view to cowl the secure space
}
}
struct CoinOptionView: View {
let cash: Int
let worth: String
let isSelected: Bool
var physique: some View {
VStack {
Textual content("(cash) cash")
.font(.headline)
Textual content(worth)
.font(.subheadline)
}
.padding()
.background(isSelected ? Colour.yellow : Colour.grey)
.cornerRadius(10)
}
}
Adjusting the offset values for the Picture contained in the CoinPopUp view.
Utilizing .background(Colour.clear) for the modal.
Guaranteeing the CoinPopUp view covers your entire display screen utilizing .body(maxWidth: .infinity, maxHeight: .infinity) and .edgesIgnoringSafeArea(.all).
Regardless of these makes an attempt, the picture doesn’t prolong past the modal boundaries as meant.
How can I prolong the picture past the modal boundaries in SwiftUI to realize the overlapping impact just like this? Any ideas or insights could be significantly appreciated. Thanks!