I'm displaying a GKGameCenterViewController
after successfully authenticating and on iOS 18.0 and 18.1, I get a black screen. As a sanity check GKLocalPlayer.local.isAuthenticated
is also returning true. The same code works just fine on iOS 17. Is there something that needs to be done on iOS 18 and above?
GKGameCenterViewController Is Blank On iOS 18
After digging in a bit more, it appears that the view controller has to be presented via a sheet or full screen modal. Previously I was using a switch statement to show the view and that is no longer working. However, this workaround still has some bugs revolving around the view controller so it still doesn't not work for my needs.
- Are you presenting the GKGameCenterViewController by pushing it on the navigation stack? If so what is the behavior if you switch that to presenting it modally?
- Do you see the Game Center welcome banner when the game launches and the player is authenticated? If so, what happens when you tap on the banner?
-
I’m using SwiftUI to present the view. Below is the relevant code. When I change it to presenting modally in SwiftUI using sheet or fullScreenCover, it does present.
-
I didn't even know that was tappable, but when I do it does open GameCenter in app.
public var body: some View {
ZStack {
switch gameKitManager.status {
case .authenticated:
Color.accentColor
.edgesIgnoringSafeArea(sizeClass == .compact ? .top : .all)
.opacity(0.6)
ProgressView()
.scaleEffect(1.5)
GKGameCenterView(dismiss: dismiss)
.edgesIgnoringSafeArea(sizeClass == .compact ? .top : .all)
.opacity(showGameKitCenterView ? 1 : 0)
.onAppear {
withAnimation(.linear(duration: 0.75)){
showGameKitCenterView = true
}
}
case .notAuthenticated(let vc):
GKAuthenticationView(vc: vc)
case .error(let error):
createErrorView(error)
case .none:
authenticateButton()
}
}
.navigationBarHidden(true)
.navigationTitle("Achievements")
}
public struct GKGameCenterView: UIViewControllerRepresentable {
let viewController = GKGameCenterViewController()
let dismiss: ()->Void
public func makeUIViewController(context: Context) -> GKGameCenterViewController {
viewController.gameCenterDelegate = context.coordinator
return viewController
}
public func updateUIViewController(_ uiViewController: GKGameCenterViewController, context: Context) {
}
public func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
@MainActor
public final class Coordinator: NSObject, @preconcurrency GKGameCenterControllerDelegate {
let parent: GKGameCenterView
// MARK: - Initializer
init(_ parent: GKGameCenterView) {
self.parent = parent
}
// MARK: - GKGameCenterControllerDelegate
public func gameCenterViewControllerDidFinish(_ gameCenterViewController: GKGameCenterViewController) {
gameCenterViewController.dismiss(animated: true, completion: nil)
parent.dismiss()
}
}
}