SwiftUI App crashes after second continuous open - swift

I have a working SwiftUI app with a start animation that appears to sometimes cause it to crash - this happens only when the user quits the app completely right before the animation reaches its endpoint and then immediately reopens the app - it skips the launch screen, goes straight to the main one, and then crashes. I have put my code below - thank you for your help.
import SwiftUI
import PDFKit
struct ContentView: View {
#Environment(\.presentationMode) var presentationMode
#Environment(\.scenePhase) var scenePhase
#State var inside = false
#AppStorage("ShowLoadingScreen") var showLoadingScreen = UserDefaults.standard.value(forKey: "ShowingLoadingScreen") as? Bool ?? true
var body: some View {
NavigationView {
ZStack {
Rectangle()
.ignoresSafeArea()
.foregroundColor(Color("LightBlue"))
.navigationTitle("Home")
.navigationBarHidden(true)
VStack {
if inside || !showLoadingScreen{
Spacer()
Text("Bugle") .foregroundColor(Color("DarkBlue"))
.font(Font.custom("Copperplate", size: UIScreen.main.bounds.height * 0.1)) .padding(.top, UIScreen.main.bounds.height * 0.015)
.multilineTextAlignment(.center)
.padding()
Spacer()
.navigationBarHidden(true)
NavigationLink {
MonthlyBugleView()
.navigationTitle("This Month's Bugle")
} label: {
ZStack {
RoundedRectangle(cornerRadius: 100)
.frame(width: UIScreen.main.bounds.width * 0.9, height: UIScreen.main.bounds.height * 0.15)
.opacity(0.8)
Text("This Month's Bugle").font(Font.custom("Copperplate", size: UIScreen.main.bounds.height * 0.05)) .padding(.top, UIScreen.main.bounds.height * 0.015)
.foregroundColor(.white)
.padding()
}
}
Spacer()
NavigationLink {
PDFSwiftUIView(StringToBeLoaded: "SampleLink")
} label: {
ZStack {
RoundedRectangle(cornerRadius: 100)
.frame(width: UIScreen.main.bounds.width * 0.9, height: UIScreen.main.bounds.height * 0.15)
.opacity(0.8)
.foregroundColor(Color("DarkBlue"))
Text("Previous Bugles").font(Font.custom("Copperplate", size: UIScreen.main.bounds.height * 0.05)) .padding(.top, UIScreen.main.bounds.height * 0.015)
.foregroundColor(.white)
.padding()
}
}
Spacer()
NavigationLink {
MoreWinaduStuffView()
.navigationBarHidden(true)
} label: {
ZStack {
RoundedRectangle(cornerRadius: 100)
.frame(width: UIScreen.main.bounds.width * 0.9, height: UIScreen.main.bounds.height * 0.15)
.opacity(0.8)
Text("More Stuff").font(Font.custom("Copperplate", size: UIScreen.main.bounds.height * 0.05)) .padding(.top, UIScreen.main.bounds.height * 0.015)
.foregroundColor(.white)
}
}
Spacer()
} else if showLoadingScreen{
StartAnimationView()
.transition(.opacity)
}
}
.onAppear( perform: {
DispatchQueue.main.asyncAfter(deadline: .now()+3.5){
withAnimation {
inside.toggle()
showLoadingScreen = false
}
}
}
)
}
} .onChange(of: scenePhase) { newPhase in
if newPhase == .inactive {
showLoadingScreen = true
} else if newPhase == .active {
if inside == true{
showLoadingScreen = false
}
} else if newPhase == .background {
showLoadingScreen = true
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
and this is my StartAnimationView:
import SwiftUI
struct StartAnimationView: View {
let color: UIColor = UIColor(red: 29/255.0, green: 161/255.0, blue: 242/255.0, alpha: 1)
#State var animate: Bool = false
#State var offset: CGFloat = 0
var body: some View {
VStack{
//Content
ZStack{
Color("LightBlue")
Image("sample start")
.resizable()
.scaledToFit()
.padding()
.offset(x: 0, y: offset)
.foregroundColor(.white)
.frame(width: 150, height: 150, alignment: .center)
.scaleEffect(animate ? UIScreen.main.bounds.height * 0.2 : UIScreen.main.bounds.height * 0.0075)
.animation(.easeIn(duration: 3.5), value: animate)
.animation(.easeIn(duration: 0.1), value: offset)
} .ignoresSafeArea()
}.onAppear{
DispatchQueue.main.asyncAfter(deadline: .now()+0.3){
offset = 8
animate.toggle()
}
}
}
}
struct StartAnimationView_Previews: PreviewProvider {
static var previews: some View {
StartAnimationView()
}
}

Your actions in onChange of newPhase may confuse SwiftUI as you ask SwiftUI to show animation when going to inactive or background.

Related

Image movement & animation

How can I take a image on SplashView() and make it go to the top right hand corner on Home() view during the animation between the two?
SplashView()
struct SplashView: View {
// 1.
#State var isActive:Bool = false
var body: some View {
VStack {
// 2.
if self.isActive {
// 3.
Home()
.onAppear {
print("IsVerificationSent: \(RequestedVerification)")
}
} else {
// 4.
Image("logo")
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
.overlay {
RoundedRectangle(cornerRadius: 30)
.stroke(.white, lineWidth: 1)
}
.shadow(color: Color.black.opacity(0.5), radius: 7)
}
}
// 5.
.onAppear {
// 6.
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
// 7.
withAnimation {
self.isActive = true
}
}
}
}
}
Home()
struct Home: View {
var body: some View {
VStack {
Image("logo")
.resizable()
.scaledToFill()
.offset(y: 25)
.frame(width: 50, height: 50)
.overlay {
RoundedRectangle(cornerRadius: 10)
.stroke(.white, lineWidth: 1)
.offset(y: 25)
}
.shadow(radius: 2)
Spacer(minLength: 0)
}
}
}
And since I can't put the full Home() view on here, how can I go about adjusting to make it look the best possible?

SwiftUI WatchOS: Animation behaves strangely when placed inside a list?

I have this pulse animation below which works well by itself, but when I place it inside of a List then the animation of the circles pulsing is correct but all of the circles also move vertically from the top to the center of the screen as well? Outside of a list the circles remain in the center. Why is a list causing this and how to get around?
import SwiftUI
struct HeartRatePulseView: View {
#State var animate = false
#Environment(\.scenePhase) private var scenePhase
func circlesColor() -> Color {
Color.blue
}
var body: some View {
VStack(spacing: -3) {
ZStack {
ZStack {
GeometryReader { geometry in
ZStack {
Circle().fill(circlesColor().opacity(0.25)).frame(width: geometry.size.width, height: geometry.size.height).scaleEffect(self.animate ? 1 : 0.01)
Circle().fill(circlesColor().opacity(0.35)).frame(width: geometry.size.width * 0.79, height: geometry.size.height * 0.79).scaleEffect(self.animate ? 1 : 0.01)
Circle().fill(circlesColor()).frame(width: geometry.size.width * 0.60, height: geometry.size.height * 0.60)
}
.frame(width: geometry.size.width, height: geometry.size.height)
}
}
.onAppear { self.animate = true }
.onChange(of: scenePhase, perform: { newValue in
if newValue == .active {
self.animate = true
} else {
self.animate = false
}
})
.animation(animate ? Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true) : .default)
}
}
.frame(height: 145)
}
}
struct HeartRatePulseView_Previews: PreviewProvider {
static var previews: some View {
List {
HeartRatePulseView()
}
.listStyle(.carousel)
}
}
Ok, if you change the animation method slightly it works,
Note the value argument, it seems this is the new way to animate
.animation(animate ? Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true) : nil, value: animate)
import SwiftUI
struct HeartRatePulseView: View {
#State var animate = false
#Environment(\.scenePhase) private var scenePhase
func circlesColor() -> Color {
Color.blue
}
var body: some View {
VStack(spacing: -3) {
ZStack {
ZStack {
GeometryReader { geometry in
ZStack {
Circle().fill(circlesColor().opacity(0.25)).frame(width: geometry.size.width, height: geometry.size.height).scaleEffect(self.animate ? 1 : 0.01)
Circle().fill(circlesColor().opacity(0.35)).frame(width: geometry.size.width * 0.79, height: geometry.size.height * 0.79).scaleEffect(self.animate ? 1 : 0.01)
Circle().fill(circlesColor()).frame(width: geometry.size.width * 0.60, height: geometry.size.height * 0.60)
}
.frame(width: geometry.size.width, height: geometry.size.height)
}
}
.onAppear { self.animate = true }
.onChange(of: scenePhase, perform: { newValue in
if newValue == .active {
self.animate = true
} else {
self.animate = false
}
})
.animation(animate ? Animation.easeInOut(duration: 1.5).repeatForever(autoreverses: true) : nil, value: animate)
}
}
.frame(height: 145)
}
}
struct HeartRatePulseView_Previews: PreviewProvider {
static var previews: some View {
List {
HeartRatePulseView()
HeartRatePulseView()
}
.listStyle(.carousel)
}
}

I'd like to use the navigation link.Newbie Wang is in the process of hair loss

I want to use Navigationlink. I've been a novice for 2 weeks since I started.I am currently learning SwiftUi.
I created "OnboredView" after watching YouTube, but I don't know how to connect "OnboredView" to "CountentView".
NavigationView(){
NavigationLink(destination: OnboardView())
I learned how to make it like this through YouTube, but I don't know what to do now. I put it here and there, but the red errors bother me.
Tell me how to connect "NavigationLink" by pressing the button on "CountentView".
I'd like to click "Chevron.Light" to move on to "OnboredView."And if possible, please let me know how I can get rid of the "onboard screen" on the second run?
I am not good at English.I'm sorry. I'm experiencing hair loss again.
import SwiftUI
struct ContentView: View {
#State private var animate: Bool = false
var body: some View {
ZStack{
ZStack{
Image("rogo1")
.resizable()
.frame(width: 75, height: 75)
.offset(y: animate ? -100 : 0)
}
ZStack{
Image("rogo2")
.resizable()
.frame(width: 75, height: 75)
.offset(y: animate ? -100 : 0)
}
VStack {
HStack {
Spacer()
Image("images (1)")
.resizable()
.frame(width: 300, height: 300)
.offset(x: animate ? 300 : 150, y: animate ? -300 : -150)
}
Spacer()
HStack {
Image("images (1)")
.resizable()
.frame(width: 400, height: 400)
.offset(x: animate ? -500 : -150, y: animate ? 500 : 150)
Spacer()
}
}
ZStack(alignment: .bottom){
GeometryReader { g in
VStack (alignment: .leading, spacing: 20){
Text("안녕하세요!")
.font(.title)
.fontWeight(.semibold)
.padding(.top, 20)
//인삿말과 회원가입
Text("기분 좋은 매일습관을 만들기 위한 앱 ( ) 입니다! 시간표와 더불어 루틴을 함께 할수
있도록 설계 되었습니다.저희 ( )와 함께 계획해봐요!")
.fontWeight(.medium)
.multilineTextAlignment(.center)//중앙으로 결집
.padding(5)
ZStack {
Button(action: {},label: {
Image(systemName: "chevron.right")
.font(.system(size:20, weight: .semibold))
.frame(width: 60, height: 60)
.foregroundColor(.black)
.background(Color.white)
.clipShape(Circle())
.overlay(
ZStack {
Circle()
.stroke(Color.black.opacity(0.04),lineWidth: 4)
Circle()
.trim(from: 0, to: 0.03)
.stroke(Color.white,lineWidth: 4)
.rotationEffect(.init(degrees: -40))
})
})
.padding(-10)
}
Spacer()
}
.frame(maxWidth: .infinity)
.padding(.horizontal, 30)
.background(Color.green)
.clipShape(CustomShape(leftCorner: .topLeft, rightCorner: .topRight,
radii: 20))
.offset(y: animate ? g.size.height : UIScreen.main.bounds.height)
}
}.frame(height: 275)
//여기까지 짤라도 됨 온보드
}
.frame(maxWidth: .infinity)
.edgesIgnoringSafeArea(.all)
.onAppear(perform: {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
withAnimation(Animation.easeOut(duration: 0.45)){
animate.toggle()
}
}
})
}
{
struct CustomShape: Shape {
var leftCorner: UIRectCorner
var rightCorner: UIRectCorner
var radii: CGFloat
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners:
[leftCorner,rightCorner], cornerRadii: CGSize(width: radii, height: radii))
return Path(path.cgPath)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
Group {
}
}
}
}
import SwiftUI
struct OnboardView: View {
#AppStorage("currentPage") var currentPage = 1
var body: some View {
if currentPage > totalPages {
Home()
}else{
WalkthroughScreen()
}
}
}
struct OnboardView_Previews: PreviewProvider {
static var previews: some View {
OnboardView()
}
}
struct Home: View {
var body: some View{
Text("welcome To Home!!!")
.font(.title)
.fontWeight(.heavy)
}
}
//..Walkthrough Screen..
struct WalkthroughScreen: View {
#AppStorage("currentPage") var currentPage = 1
var body: some View {
//For Slide Animation
ZStack{
//Changing Between Views..
if currentPage == 1 {
ScreenView(image: "image1", title: "Step1", detail: "", bgColor:
Color(.white))
//transition(.scale)영상에서는 넣었으나 오류가나서 사용하지 못함
}
if currentPage == 2 {
ScreenView(image: "image2", title: "Step2", detail: "", bgColor:
Color(.white))
}
if currentPage == 3 {
ScreenView(image: "image3", title: "Step3", detail: "아니 ㅡㅡ 이런 방법이 유레카",
bgColor: Color(.white))
}
}
.overlay(
Button(action: {
//changing views
withAnimation(.easeInOut){
if currentPage < totalPages {
currentPage += 1
}else{
currentPage = 1
//For app testing ONly
}
}
}, label: {
Image(systemName: "chevron.right")
.font(.system(size: 20, weight: .semibold))
.foregroundColor(.black)
.frame(width: 60, height: 60)
.clipShape(Circle())
//strclulat Slider
.overlay(
ZStack{
Circle()
.stroke(Color.black.opacity(0.04),lineWidth: 4
Circle()
.trim(from: 0, to: CGFloat(currentPage) /
CGFloat(totalPages))
.stroke(Color.green,lineWidth: 4)
.rotationEffect(.init(degrees: -99))
}
.padding(-15)
)
})
.padding(.bottom,20)
,alignment: .bottom
)
}
}
struct ScreenView: View {
var image: String
var title: String
var detail: String
var bgColor: Color
#AppStorage("currentPage") var currentPage = 1
var body: some View {
VStack(spacing:20){
HStack {
//Showing it only for first page..
if currentPage == 1{
Text("Hello Members!")
.font(.title)
.fontWeight(.semibold)
//Letter Spacing
.kerning(1.4)
}else{
//Back Butten..
Button(action: {
withAnimation(.easeInOut){
currentPage -= 1
}
}, label: {
Image(systemName: "chevron.left")
.foregroundColor(.white)
.padding(.vertical,10)
.padding(.horizontal)
.background(Color.black.opacity(0.4))
.cornerRadius(10)
})
}
Spacer()
Button(action: {
withAnimation(.easeInOut){
currentPage = 4
}
}, label: {
Text("Skip")//글자입력
.fontWeight(.semibold)//글자 폰트변경
.kerning(1.2)//글자간 간격 조정
})
}
.foregroundColor(.black)//그라운드 컬러 변경
.padding()
Spacer(minLength: 0)//수평,수직 줄바꿈
Image(image)//이미지 삽입
.resizable()//크기 확대
.aspectRatio(contentMode: .fit)//이미지 크기
Text(title)
.font(.title)//폰트 크기변경
.fontWeight(.bold)//폰트 두께 변경
.foregroundColor(.black)//색깔 변경
.padding(.top)
//Change with your Own Thing..
Text(detail)
.fontWeight(.semibold)
.kerning(1.3)//자간조정
.multilineTextAlignment(.center)//텍스트를 중앙으로 결집
Spacer(minLength: 220)//minimun Spacing When phone is reducing수직위치 조정
}
.background(bgColor.cornerRadius(10).ignoresSafeArea())
}
}
var totalPages = 3

SwiftUI .cornerRadius on Image not showing up

I am currently working on a SwiftUI Chat View project, and I am trying to round the corner of an image, which is loaded via a URL and converted from UIImage to Image. Any ideas why .cornerRadius(10) isn't working?
Image(uiImage: imageFromFirebase!)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: UIScreen.main.bounds.width / 1.5, alignment: isCurrentUser ? .trailing : .leading)
.clipped()
.cornerRadius(10)
Here is the full container – there is probably a lot of unnecessary stuff here but in case it helps:
struct ContentMessageView: View {
var contentMessage: String
var isCurrentUser: Bool
var type: String
var name: String
var color: Color
var image: UIImage?
#State private var imageFromFirebase: UIImage?
func imageLoadFromURL(){
HTTPRequest.fetchImage(self.contentMessage) { (image) in
if image != nil {
imageFromFirebase = image!
}
}
}
var body: some View {
VStack{
if type == "image" {
if !isCurrentUser {
HStack{
Text(name).font(.caption).foregroundColor(Color.black.opacity(0.2)).padding(.horizontal)
Spacer()
}
}
HStack{
if isCurrentUser {
Spacer()
}
if imageFromFirebase != nil {
ZStack{
Image(uiImage: imageFromFirebase!)
.resizable()
.scaledToFit()
.cornerRadius(10)
.frame(width: UIScreen.main.bounds.width / 1.5, alignment: isCurrentUser ? .trailing : .leading)
// .overlay(RoundedRectangle(cornerRadius: 10)
.background(Color.black)
// .stroke(isCurrentUser ? Color(UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 1.0)) : color, lineWidth: 5))
}
.shadow(color: Color.black.opacity(0.05), radius: 10)
}
if !isCurrentUser {
Spacer()
}
}.padding(.horizontal, 10)
}
}.onAppear(){
self.imageLoadFromURL()
}
}
}
It is working fine, you did use wrong syntax and placement for code!
import SwiftUI
struct ContentView: View {
var body: some View {
if let unwrappedUIImage: UIImage = UIImage(named: "your image name here") {
Image(uiImage: unwrappedUIImage)
.resizable()
.scaledToFit()
.cornerRadius(30)
.frame(width: 300, height: 300, alignment: .center)
}
}
}

SwiftUI Custom Slider with max Value

I use this great code to get a slider. here
but how can i set the max value to 30 not to 100?
this example is from 0 to 100.
hope everyone can help.
struct CustomView: View {
#Binding var percentage: Float // or some value binded
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .leading) {
Rectangle()
.foregroundColor(.gray)
Rectangle()
.foregroundColor(.accentColor)
.frame(width: geometry.size.width * CGFloat(self.percentage / 100))
}
.cornerRadius(12)
.gesture(DragGesture(minimumDistance: 0)
.onChanged({ value in
self.percentage = min(max(0, Float(value.location.x / geometry.size.width * 100)), 100)
}))
}
}
}
You just need to replace the 100 with 30 to get bound from 0 to 30
struct CustomView: View {
#Binding var percentage: Float // or some value binded
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .leading) {
Rectangle()
.foregroundColor(.gray)
Rectangle()
.foregroundColor(.accentColor)
.frame(width: geometry.size.width * CGFloat(self.percentage / 30))
}
.cornerRadius(12)
.gesture(DragGesture(minimumDistance: 0)
.onChanged({ value in
self.percentage = min(max(0, Float(value.location.x / geometry.size.width * 30)), 30)
print(self.percentage)
}))
}
}
}