Animate an animated gif only while pressing the button - swiftui

This is my code :
struct Animation: View {
var body: some View{
Image("Animation.gif")
}
}
i have a gif image and i want this image to only be animated once a button click only, i need help!
and if there is no button click then it won't be animated thank you

As far as I know, SwiftUI doesn't have anything that can do this. Instead, you should use an #State variable to track whether or not the button has been pressed. If it hasn't, show a non-animated image, and if it has, show a different image, but animated this time.
Something like this:
#State var buttonIsClicked = false
let nonAnimated = <static image>
let animated = <your gif>
var body: some View {
VStack {
if buttonIsClicked {
animated
} else {
nonAnimated
}
Button("Click to animate") {
buttonIsClicked.toggle()
}
}
}

Related

SwiftUI: On every Button click create a View and dismiss/delete it after a few seconds

I want to create an effect if you press on a button a view should be visible above the button and fade away. I have already this effect:
struct AnimationView: View {
#Binding var animate: Bool
var body: some View {
Text("-1")
.bold()
.opacity(animate ? 0 : 1)
.offset(y: animate ? -50 : 0)
}
}
My button which triggers $animate
#State var animate = false
Button {
withAnimation(.linear(duration: 1)) {
animate = true
}
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
animate = false
}
} label: {
'SomeView'
}
But my problem is that I only can have one of this View. I want to kinda spam the button which creates Views as much I pressed the button, which all fades away. Is this possible?
You can change the #State property to this #State var animate: [Your data type or Void if you don't need one] = []. On each tap, you can append a () or any data type that you want and construct the views with that array, and then remove them with your timers.

Scroll View Items Come Over the Navigation Bar in SwiftUI

I am new to SwiftUI. I made a custom nav bar. and added a scroll view below it. The problem I am getting is when I scroll down, the data inside scroll view comes over the navigation bar. Here is the screenshot:
My code is:
struct NewsfeedView: View {
var newsfeedModel: [NewsFeedData]
var body: some View {
VStack {
CustomNavBar(navTitle: "Newsfeed")
ScrollView {
LazyVStack{
ForEach(newsfeedModel) { modelData in
NewsFeedTableViewCell(newsFedd: modelData)
}
}
}
}.ignoresSafeArea()
}
}
Does anyone knows what is the issue?
If it's undesired then just clip it, like
ScrollView {
// .. content here
}
.clipped() // << here !!

use Firestore model value as toggle to present fullscreen view in SwiftUI

I have two screens in a SwiftUI app.
Screen A is displayed after the app launch and contains a button which will update the value for currentWorkoutID on the user model and save that modification to a Firestore database.
Screen B is shown from screen A when currentWorkoutID is not nil on the user model.
The problem that I'm seeing is that when I press the button in screen A, screen B immediately shows up (no animation), then is dismissed with animation and then is shown again with no animation.
I'm unsure what the issue is or how to solve it.
struct TrainingProgramDetails: View{
#EnvironmentObject var workoutCompletionStore: WorkoutCompletionDataStore
var presentWorkoutScreenBinding: Binding<Bool> {
Binding(get: {
return userDataStore.user.profileData.currentWorkoutID != nil
},
set: { value in
//nothing to do here
})
}
var body: some View {
let nextWorkoutID = userDataStore.user.profileData.currentWorkoutID
GeometryReader { screenGeometryProxy in
let imageHeight = screenGeometryProxy.size.height / 3
WorkoutsList(workouts: program.workoutsData) {
...
}
.fullScreenCover(isPresented: presentWorkoutScreenBinding,
onDismiss: {
}, content: {
WorkoutScreenAdaptor(workoutID: nextWorkoutID!,
onShowFeedback: showFeedback)
})
}
.edgesIgnoringSafeArea(.top)
}
struct User: Codable {
var profileData: ProfileData = .init()
...
}
struct ProfileData: Codable {
var currentWorkoutID:String?
...
}
Turns out the problem was on a container to this screen that would cause this screen to be taken out of view and then reloaded.

Making a SwiftUI view disappear

Good day.
Is there a way to make a child view that is being called from the parent view disappear if, let's say, a bool condition is true? I want to make it completely disappear, not hidden via opacity, isHidden, etc.
I want to know if this is possible, thank you!
In SwiftUI you can conditionally show a view like...
if someCondition {
YourConditionalView()
}
This will only show that view if the someCondition is true.
From your comment...
struct YourView: View {
#State var showView = true
var body: some View {
VStack {
if showView {
Text("Hello there!")
}
Button {
self.showView.toggle()
} label: {
Text("Press me")
}
}
}
}
This view will start with a label "Hello there!" and a button. When you tap the button the showView boolean is toggled. This will then cause the label to be added/removed from the view based on the value of showView.

SwiftUI small modal view

I am starting out in SwiftUI and have an issue.
I have a main view loads a modal view, on iPhone this goes full screen, iPad by default covers part of the screen.
The below code appears to do the 'default' loads a view that is centered but not full screen.
What id ideally like is to be able to make the model view smaller. It is a login screen where user enters login details.
Using storyboards, I could achieve this with 'preferredcontentsize' but SwiftUI comparisons don't appear to work.
struct Login_View: View {
#State private var showingSheet = false
var body: some View {
Button("Show Alert") {
showingSheet = !showingSheet
}
.sheet(isPresented:$showingSheet) {
Credentials_View()
}
}
}
(Below is the modal view, atm it just shows some colours whilst I get to grips with that is going on)
struct Credentials_View: View {
var body: some View {
GeometryReader { metrics in
VStack(spacing: 0) {
Color.red.frame(height: metrics.size.height * 0.43)
Color.green.frame(height: metrics.size.height * 0.37)
Color.yellow
}
}
}
}
IOS 16+
As of iOS 16, a half sheet can be created using .sheet where the displayed view(example Credentials_View) has the .presentationDetents set to .medium.
struct Login_View: View {
#State private var showingSheet = false
var body: some View {
Button("Show Alert") {
showingSheet = !showingSheet
}
.sheet(isPresented:$showingSheet) {
Credentials_View()
.presentationDetents([.medium])
}
}
}
Result:
And .presentationDragIndicator can be added to make the indicator visible:
.presentationDragIndicator(.visible)
Result: