ZStack has extra space at the top - swiftui

The following code show weird extra space at the top. Anyone know what's the issue?
ZStack(alignment: .top) {
Image(imageName)
.resizable()
.aspectRatio(contentMode: .fill)
.scaleEffect(imageScale)
.blur(radius: imageScale > 1 ? 5 : 0)
.animation(.easeOut)
}
.frame(width: selected ? UIScreen.main.bounds.width : width ,
height: selected ? UIScreen.main.bounds.height : height)
.cornerRadius(30)
.shadow(color: Color.black.opacity(0.3), radius: 15, x: 0, y: 20)

I just figured out the solution. It's .cornerRadius(30) that cause the problem. Adding .edgesIgnoringSafeArea(.all) will not fix the issue unless you remove .cornerRadius(30). I hope this answer help someone else.

Related

Getting rid of SwiftUI ScrollView top padding

I just can't seem to get rid of the ~6 height padding(?) at the top of ScrollView. I've tried setting padding to 0 on both the ScrollView itself and on it's content. I've tried using SwiftUI-Introspect to get at the content insets, but they appear to already be 0 for the top. I could just use offset(y: -6), but I'd like to understand what is causing the padding. Does anyone know?
var body: some View {
VStack(spacing: 0) {
Rectangle()
.frame(width: UIScreen.main.bounds.width, height: 200)
.foregroundColor(.blue)
Rectangle()
.frame(width: UIScreen.main.bounds.width, height: 200)
.foregroundColor(.red)
ScrollView {
Rectangle()
.frame(width: UIScreen.main.bounds.width, height: 200)
.foregroundColor(.black)
}
}
}

Custom navigation bar's button doesn't work (SwiftUI)

I am currently learning SwiftUI and I followed this video to create a custom NavigationBar.
Learn how to create a custom navigation bar with a logo in SwiftUI framework and Xcode - Part 2
The buttons doesn't work when I click on it unless I don't use padding() and ignoreSafeArea(), but without using it, the navigationBar would appear on middle of the page. (I also tried use Spacer() but it didn't work)
Is there anyway to fix this issue?
Code for HomePage()
VStack{
NavigationBarView()
.padding(.horizontal, 15)
.padding(.bottom)
.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
.shadow(color: Color.black.opacity(0.1), radius: 5, x: 0, y: 5)
.ignoresSafeArea(.all, edges: .top)
Code for NavigationBarView()
HStack{
NavigationLink(
destination: PersonalMenuPage()
,label: {
ZStack {
Image("Profile")
.renderingMode(.original)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
.padding(.horizontal, 10)
Circle()
.fill(Color.red)
.frame(width:14, height: 14, alignment: .center)
.offset(x: 13, y: -10)
}
}
)
}//: hStack
Here is sample output
Sample output

How to detect whether the scrollview was scrolled or not in SwiftUI?

I have a horizontal ScrollView and would like to provide a function that when the first element is not visible anymore an arrow should appear to signalize that there are some other elements.
I've tried the DragGesture() to read the translation.width but it seems to be buggy in combination with the ScrollView.
So I'm looking for a way to detect whether the ScrollView was scrolled and how far. Is there any way?
private let gridItems = [GridItem(.flexible())]
ScrollView(.horizontal, showsIndicators: false) {
HStack{
LazyHGrid(rows: gridItems){
ForEach(viewModel.imageOptions, id: \.self){ image in
ZStack {
Image(image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 60, height: 60)
.background(Color.white)
.clipShape(Circle())
.background(
Circle()
.clipShape(Circle())
.shadow(color: Color.black.opacity(0.4), radius: 3, x: 5.0, y: 5.0)
)
.onTapGesture {
print("selected")
}
.padding(15)
Circle()
.strokeBorder(Color.orange, lineWidth: 5)
.frame(width: 70, height: 70)
}
}
}
}
}
}

Reversed animation with repeatForever()

I'm trying to implement an error badge with a pulsating circle in the background. whenever I click on it multiple time it pulses inwards rather than outwards. I'm unable to understand this behaviour. Please suggest me the correct approach.
Image(systemName: "exclamationmark")
.background(
ZStack{
Circle()
.fill(Color.red.opacity(0.3))
.frame(width: 20, height: 20)
Circle()
.fill(Color.red.opacity(0.4))
.frame(width: 20, height: 20)
.scaleEffect(carError ? 1.5 : 1)
.onTapGesture(perform: {
carError.toggle()
})
}
.animation(carError ? Animation.easeIn(duration: 0.7).repeatForever() : nil)
)
.font(.footnote)
.foregroundColor(Color("ColorError"))
.position(x: 100, y: 100)
You just need to toggle back to .default animation instead of nil
.animation(carError ? Animation.easeIn(duration: 0.7).repeatForever() : .default)

Clipped not actually clips the Image in SwiftUI

I am trying to clip the image and as we see the UI it looks fine but actually it doesn't clip the image which causes other UI elements to unresponsive.
Here the code I am using.
struct ImageContentView: View {
var urls:[String] = [
"https://lh3.googleusercontent.com/proxy/80im-IBfLODpLDj8d02uEpSVIhqdjen6H6CeFwgRBxeua-Dgw0R3WONFj1Gk8CwB_MufmC9rQ8qHjyWMejwFcJ1PA2s8AAu5WVsmJA=s0-d",
"https://wallpaperaccess.com/full/530919.jpg"
]
var body: some View {
ScrollView{
VStack{
Button(action: {
}, label: {
Text("Hello")
})
VStack(spacing: 20.0) {
ForEach(self.urls, id:\.self) { url in
WebImage(url: URL.init(string: url)!)
.resizable()
.aspectRatio(contentMode: ContentMode.fill)
.frame(height: UIScreen.main.bounds.size.width * 0.5)
.clipped()
.cornerRadius(10.0)
.shadow(color: Color.red, radius: 10.0, x: 0, y: 0)
}
}.padding()
}
}
}
}
Here is fixed part (tested with Xcode 12 / iOS 14)
VStack(spacing: 20.0) {
ForEach(self.urls, id:\.self) { url in
WebImage(url: URL.init(string: url)!)
.resizable()
.aspectRatio(contentMode: ContentMode.fill)
.frame(height: UIScreen.main.bounds.size.width * 0.5)
.clipped()
.cornerRadius(10.0)
.shadow(color: Color.red, radius: 10.0, x: 0, y: 0)
}.contentShape(Rectangle()) // << here !!
}.padding()
Note: I don't know what is your WebImage but with Image and local images it was reproduced as well, so fix was tested.
iOS 13 and +
An other solution is combine compositingGroup and clipped:
That wraps this view in a compositing group and clips.
Note: Respect this order compositingGroup and clipped
Image(..)
.compositingGroup()
.clipped()
I have tried for the above methods but still not working.
Here is another solution for someone who have the same struggle, maybe this can help you :) This line is to disable the tap gesture of the image.
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.contentShape(RoundedRectangle(cornerRadius: 8))
.allowsHitTesting(false) // <- this is the line