Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Fallback bezel size doesn't work on first run #30

Closed
Cecile-Lebleu opened this issue Jan 24, 2024 · 2 comments
Closed

🐛 Fallback bezel size doesn't work on first run #30

Cecile-Lebleu opened this issue Jan 24, 2024 · 2 comments
Assignees
Labels
bug Something isn't working

Comments

@Cecile-Lebleu
Copy link

Describe the bug

When setting a fallback size that's not zero with ifZero: true, the fallback size isn't applied when the app loads on iPhone SE / 7. As far as I can tell, it only shows the expected radius after updating it manually.

Reproduction steps

When I run the following code on an iPhone SE in simulator and on a physical iPhone 7, the corners show up completely sharp. The corners then update to the correct cornerRadius only after changing edgeSize. No errors or warnings are shown.

import SwiftUI

@main
struct BezelKit_TestApp: App {
	var body: some Scene {
		WindowGroup {
			ContentView()
				.onAppear() {
					// Sets a fallback value of 10.0 and enables zero-check
					CGFloat.setFallbackDeviceBezel(40.0, ifZero: true)
				}
		}
	}
}
import BezelKit
import SwiftUI

struct ContentView: View {
	@State private var edgeSize: CGFloat = 10
	
	@State private var showErrorAlert: Bool = false
	@State private var errorMessage: String = ""
	
	var body: some View {
		let outerBezel = CGFloat.deviceBezel
		let innerBezel = outerBezel - edgeSize
		
		VStack {
			Image(systemName: "globe")
				.imageScale(.large)
				.foregroundStyle(.tint)
			Text("Hello, world!")
			Slider(value: $edgeSize, in: 0...55)
			Text("\(edgeSize)")
		}
		.padding()
		.frame(maxWidth: .infinity, maxHeight: .infinity)
		.background(Color.yellow)
		.clipShape(RoundedRectangle(cornerRadius: innerBezel))
		.padding(edgeSize)
		.ignoresSafeArea()
		
		.alert(isPresented: $showErrorAlert) {
			Alert(title: Text("Error"),
				  message: Text(errorMessage),
				  dismissButton: .default(Text("Got it!")))
		}
		.onAppear {
			DeviceBezel.errorCallback = { error in
				errorMessage = error.localizedDescription
				showErrorAlert = true
			}
		}
	}
}

Expected behaviour

View should have rounded corners when app first loads.

Screenshots

bezelkit

Device information

iPhone SE in simulator, physical iPhone 7 running v 15.7.9

@Cecile-Lebleu Cecile-Lebleu added the bug Something isn't working label Jan 24, 2024
@markbattistella
Copy link
Owner

markbattistella commented Jan 24, 2024

Good catch!

The issue lies with .onAppear and @main vs ContentView().

I updated your code to be this as a test:

@main
struct BezelKit_TestApp: App {
  init() { CGFloat.setFallbackDeviceBezel(40.0, ifZero: true) }
  var body: some Scene {
    WindowGroup {
      ContentView()
        .onAppear {
          CGFloat.setFallbackDeviceBezel(40.0, ifZero: true)
          let _ = print("@main - identifier: ", ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "")
          let _ = print("@main - bezel:", CGFloat.deviceBezel)
        }
    }
  }
}

struct ContentView: View {
  @State private var edgeSize: CGFloat = 10
  @State private var showErrorAlert: Bool = false
  @State private var errorMessage: String = ""
  var body: some View {
   // ...
  }
  .onAppear {
    // exiting errorCallback
    let _ = print("@onAppear - identifier: ", ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "")
    let _ = print("@onAppear - bezel:", CGFloat.deviceBezel)
  }
}

When I run it, the output to the console is in reverse order from what we would assume:

@onAppear - identifier:  iPhone14,6
@onAppear - bezel: 40.0
@main - identifier:  iPhone14,6
@main - bezel: 0.0

That means that ContentView initialises before the .onAppear of @main.

I'm not sure if this is intended or an Apple bug - but one way to get around it is to add an init() {} to the @main:

@main
struct BezelKit_TestApp: App {
  init() { CGFloat.setFallbackDeviceBezel(40.0, ifZero: true) }
  var body: some Scene {
    WindowGroup {
      ContentView()
        .onAppear {
          let _ = print("@main - identifier: ", ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] ?? "")
          let _ = print("@main - bezel:", CGFloat.deviceBezel)
        }
    }
  }
}

This results in the following:

@onAppear - identifier:  iPhone14,6
@onAppear - bezel: 40.0
@main - identifier:  iPhone14,6
@main - bezel: 40.0

Which has solved it for the run. Not sure if that is the best solution or efficient at this point, but it works for now.

@markbattistella
Copy link
Owner

Fixed in #31

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants