ios - SwiftUI MapKit breaks the custom navigation bar - Stack Overflow

When I use non-deprecated Map() functions, it breaks the custom navigation bar and displays the system&

When I use non-deprecated Map() functions, it breaks the custom navigation bar and displays the system's default navigation bar instead. I haven’t been able to find a solution to this issue anywhere.

import SwiftUI

struct CustomNavigationBarView: ViewModifier {
    @Environment(\.presentationMode) var presentationMode
    var showBackButton: Bool 
    
    init(showBackButton: Bool = false) {
        self.showBackButton = showBackButton
        
        let navBarAppearance = UINavigationBarAppearance()
        
        navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor(Color.white)]
        
        UINavigationBar.appearance().standardAppearance = navBarAppearance
        UINavigationBar.appearance()pactAppearance = navBarAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
        
        navBarAppearance.configureWithTransparentBackground()
                        
        navBarAppearance.backgroundImage = makeLinearGradient(
                    size: .init(width: 1, height: 1),
                    colors: [.nav1, .nav2]
                )
        navBarAppearance.shadowImage = UIImage()
    }
    
    func body(content: Content) -> some View {
        content
            .navigationBarBackButtonHidden(true)
            .toolbar {
                if showBackButton {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button(action: {
                            presentationMode.wrappedValue.dismiss()
                        }) {
                            HStack {
                                Image(systemName: "chevron.left")
                                    .foregroundColor(.white)
                            }
                        }
                    }
                }
            }
    }
}

func makeLinearGradient(size: CGSize, colors: [UIColor]) -> UIImage {
    
    let renderer = UIGraphicsImageRenderer(size: size)
    let colors: [CGColor] = colors.map({ $0.cgColor })
    let gradient = CGGradient(
        colorsSpace: CGColorSpaceCreateDeviceRGB(),
        colors: colors as CFArray,
        locations: [0, 1]
    )
    return renderer.image { context in
        if let gradient {
            context.cgContext.drawLinearGradient(
                gradient,
                start: CGPoint(x: 0, y: 1),
                end: CGPoint(x: size.width, y: size.height),
                options: .init()
            )
        }
    }
}
extension View {
    func navigationBarModifier(showBackButton: Bool = false) -> some View {
        self.modifier(CustomNavigationBarView(showBackButton: showBackButton))
            .navigationBarTitleDisplayMode(.inline)

    }
}  

Using the map function in this way preserves the navigation bar, but I’d rather avoid it because it’s deprecated.

let annotations = [
           City(name: "London", coordinate: CLLocationCoordinate2D(latitude: 41.015137, longitude: 28.979530))
       ]
@State private var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 41.015137, longitude: 28.979530),
        span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
ZStack(alignment: .bottom) {
       Map(coordinateRegion: $region, annotationItems: annotations) { annotation in
                    MapAnnotation(coordinate: annotation.coordinate) {
                        Image("map-loc")
                            .resizable()
                            .frame(width: 25, height: 33)
                    }
                }
} 

Using this method breaks the custom navigation bar, and the other modern functions also fail to work as expected.

let cameraPosition: MapCameraPosition = .region(.init(center: .init(latitude: 41.015137, longitude: 28.979530), latitudinalMeters: 1300, longitudinalMeters: 1300))

ZStack(alignment: .bottom) {
                Map(initialPosition: cameraPosition) {
                    Annotation("map", coordinate: .appleHQ, anchor: .bottom) {
                        Image(systemName: "map-loc")
                            .resizable()
                    }
                }
}

When I use non-deprecated Map() functions, it breaks the custom navigation bar and displays the system's default navigation bar instead. I haven’t been able to find a solution to this issue anywhere.

import SwiftUI

struct CustomNavigationBarView: ViewModifier {
    @Environment(\.presentationMode) var presentationMode
    var showBackButton: Bool 
    
    init(showBackButton: Bool = false) {
        self.showBackButton = showBackButton
        
        let navBarAppearance = UINavigationBarAppearance()
        
        navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor(Color.white)]
        
        UINavigationBar.appearance().standardAppearance = navBarAppearance
        UINavigationBar.appearance()pactAppearance = navBarAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
        
        navBarAppearance.configureWithTransparentBackground()
                        
        navBarAppearance.backgroundImage = makeLinearGradient(
                    size: .init(width: 1, height: 1),
                    colors: [.nav1, .nav2]
                )
        navBarAppearance.shadowImage = UIImage()
    }
    
    func body(content: Content) -> some View {
        content
            .navigationBarBackButtonHidden(true)
            .toolbar {
                if showBackButton {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button(action: {
                            presentationMode.wrappedValue.dismiss()
                        }) {
                            HStack {
                                Image(systemName: "chevron.left")
                                    .foregroundColor(.white)
                            }
                        }
                    }
                }
            }
    }
}

func makeLinearGradient(size: CGSize, colors: [UIColor]) -> UIImage {
    
    let renderer = UIGraphicsImageRenderer(size: size)
    let colors: [CGColor] = colors.map({ $0.cgColor })
    let gradient = CGGradient(
        colorsSpace: CGColorSpaceCreateDeviceRGB(),
        colors: colors as CFArray,
        locations: [0, 1]
    )
    return renderer.image { context in
        if let gradient {
            context.cgContext.drawLinearGradient(
                gradient,
                start: CGPoint(x: 0, y: 1),
                end: CGPoint(x: size.width, y: size.height),
                options: .init()
            )
        }
    }
}
extension View {
    func navigationBarModifier(showBackButton: Bool = false) -> some View {
        self.modifier(CustomNavigationBarView(showBackButton: showBackButton))
            .navigationBarTitleDisplayMode(.inline)

    }
}  

Using the map function in this way preserves the navigation bar, but I’d rather avoid it because it’s deprecated.

let annotations = [
           City(name: "London", coordinate: CLLocationCoordinate2D(latitude: 41.015137, longitude: 28.979530))
       ]
@State private var region = MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 41.015137, longitude: 28.979530),
        span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
ZStack(alignment: .bottom) {
       Map(coordinateRegion: $region, annotationItems: annotations) { annotation in
                    MapAnnotation(coordinate: annotation.coordinate) {
                        Image("map-loc")
                            .resizable()
                            .frame(width: 25, height: 33)
                    }
                }
} 

Using this method breaks the custom navigation bar, and the other modern functions also fail to work as expected.

let cameraPosition: MapCameraPosition = .region(.init(center: .init(latitude: 41.015137, longitude: 28.979530), latitudinalMeters: 1300, longitudinalMeters: 1300))

ZStack(alignment: .bottom) {
                Map(initialPosition: cameraPosition) {
                    Annotation("map", coordinate: .appleHQ, anchor: .bottom) {
                        Image(systemName: "map-loc")
                            .resizable()
                    }
                }
}
Share Improve this question edited Mar 25 at 17:45 Benzy Neez 23.4k3 gold badges15 silver badges44 bronze badges asked Mar 25 at 14:34 Derya KarakusDerya Karakus 132 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 1

It might help to add .toolbarBackground(.automatic, for: .navigationBar) to the ZStack that contains the Map.

Here is an adaption of your example, based on an assumption of how you are applying the view extension:

struct ContentView: View {
    let cameraPosition: MapCameraPosition = .region(.init(center: .init(latitude: 41.015137, longitude: 28.979530), latitudinalMeters: 1300, longitudinalMeters: 1300))

    var body: some View {
        NavigationStack {
            NavigationLink("Go to map") {
                ZStack(alignment: .bottom) {
                    Map(initialPosition: cameraPosition) {}
                }
                .toolbarBackground(.automatic, for: .navigationBar) // 

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744189233a4562353.html

相关推荐

  • ios - SwiftUI MapKit breaks the custom navigation bar - Stack Overflow

    When I use non-deprecated Map() functions, it breaks the custom navigation bar and displays the system&

    8天前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信