-0.4 C
New York
Saturday, February 22, 2025

ios – UINavigationController broke SwiftUI Picture and AsyncImage


I am integrating SwiftUI into UINavigationController and encounter bizarre problem when pushing a UIHostingController containing an extended Picture or AsyncImage. I would like the picture to occupy the entire display width so I exploit

      Picture("picsum-237-1900x400") 
        .resizable()
        .scaledToFill()
        .body(top: 200)
        .body(maxWidth: .infinity)

This show usually with the standard NavigationStack and NavigationLink. However once I use it with NavigationWrapper, the picture overflows from the display.

struct NavigationWrapper: UIViewControllerRepresentable {
  @ViewBuilder let rootView: () -> Content material
  
  func makeUIViewController(context: Context) -> UINavigationController {
    let navController = UINavigationController()
    let hostingController = UIHostingController(
      rootView: rootView().surroundings(.navigationController, navController)
    )
    navController.pushViewController(hostingController, animated: false)
    return navController
  }
  
  func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {}
}

Utilization:

@fundamental
struct MainApp: App {
  var physique: some Scene {
    WindowGroup {
      NavigationWrapper(rootView: { ProductView() })
    }
  }
}

struct ProductView: View {
  @Setting(.navigationController) non-public var navigationController
  
  var physique: some View {
    VStack {
      Button("Go to Product Particulars") {
        let hostingVC = UIHostingController(rootView: ProductDetailsScreen())
        navigationController?.pushViewController(hostingVC, animated: true)
      }
    }
    .navigationTitle("Merchandise")
  }
}

struct ProductDetailsScreen: View {
  var physique: some View {
    VStack {
      Picture("picsum-237-1900x400")
        .resizable()
        .scaledToFill()
        .body(top: 200)
        .body(maxWidth: .infinity)
      Spacer()
      Textual content("Product Particulars")
      Spacer()
    }
    .navigationTitle("Particulars")
  }
}

struct NavigationControllerKey: EnvironmentKey {
  static let defaultValue: UINavigationController? = nil
}

extension EnvironmentValues {
  var navigationController: UINavigationController? {
    get { self[NavigationControllerKey.self] }
    set { self[NavigationControllerKey.self] = newValue }
  }
}

To simplify the demonstration, I downloaded an analogous sized picture and use Picture as a substitute of AsyncImage:

long image from picsum

Are there some ideas that I am lacking about bridging SwiftUI and UIKit, or is that this a bug in SwiftUI and is there any workaround for it?

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles