UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

'init(destination:isActive:label:)' was deprecated in iOS 16.0

Forums > SwiftUI

Hey everyone!

I've got this itching with the 'init(destination:isActive:label:)' was deprecated in iOS 16.0. Which is the most appropriate way to fix this:

            NavigationLink(
                destination: FullScreenImageView(images: images, selectedImageIndex: selectedImageIndex ?? 0),
                isActive: Binding<Bool>(
                    get: { selectedImageIndex != nil },
                    set: { newValue in
                        if !newValue {
                            selectedImageIndex = nil
                        }
                    }
                ),
                label: {
                    EmptyView()
                }
            )
            .isDetailLink(false)

Thanks!

2      

@nixon has an itch

I've got this itching with the 'init(destination:isActive:label:)' was deprecated ...//snip// ....

Repackage your destination's data

Apple's direction for navigation seems direct enough. First consider providing a NavigationLink for your users to see on screen. For each of your links, you provide a unique value, essentially a package of data to render. Perhaps in your application, you can provide a struct containing the images (or a single image? I can't tell from your code snip...) and a boolean.

Then you provide a navigationDestination (FullScreenImageView) to display the contents of the value that your user tapped, and render the view based on the boolean value packed into the struct.

// From Apple's Documentation
NavigationStack {
    List {
        // Pack all your required content into a the value parameter. Images and booleans.
        NavigationLink("Mint", value: Color.mint) // <-- provide a package of data for your destination
        NavigationLink("Pink", value: Color.pink)
        NavigationLink("Teal", value: Color.teal)
    }
    // This is the destination for your package of data. 
    // What do you need to provide to render the next view?
    .navigationDestination(for: Color.self) { color in
        ColorDetail(color: color)  // <-- Render the tapped link using the package of data provided in the NavigationLink
    }
    .navigationTitle("Colors")
}

Keep coding

Is this a watch application you're developing?

2      

Thanks, I'm still figuring this out. No, it's not a watch app, for now iPhone.

2      

struct ImageGalleryView: View {
    let images: [String] = ["photo_adriana_01", "photo_adriana_02", "photo_adriana_03", "photo_adriana_04", "photo_adriana_05"]
    @State private var selectedImageIndex: Int?
    var body: some View {
        NavigationView {
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 10) {
                    ForEach(images.indices, id: \.self) { index in
                        GalleryItemView(imageName: images[index])
                            .onTapGesture {
                                selectedImageIndex = index
                            }
                    }
                }
            }
            .frame(height: 120)
            .padding([.leading], 15.0)
            .background(
                NavigationLink(
                    destination: FullScreenImageView(images: images, selectedImageIndex: selectedImageIndex ?? 0),
                    isActive: Binding<Bool>(
                        get: { selectedImageIndex != nil },
                        set: { newValue in
                            if !newValue {
                                selectedImageIndex = nil
                            }
                        }
                    ),
                    label: {
                        EmptyView()
                    }
                ).isDetailLink(false) // prevent treating as a detail link
            )
        }
    }
}
struct GalleryItemView: View {
    let imageName: String
    var body: some View {
        Image(imageName)
            .resizable()
            .scaledToFill()
            .frame(width: 120, height: 120)
            .clipped()
            .aspectRatio(1, contentMode: .fill)
            .cornerRadius(10)
    }
}
struct FullScreenImageView: View {
    let images: [String]
    @State private var currentPage: Int
    @State private var scale: CGFloat = 1.0
    @State private var currentScale: CGFloat = 1.0
    init(images: [String], selectedImageIndex: Int) {
        self.images = images
        self._currentPage = State(initialValue: selectedImageIndex)
    }
    var body: some View {
        ZStack {
            Color.black
                .ignoresSafeArea()
            TabView(selection: $currentPage) {
                ForEach(images.indices, id: \.self) { index in
                    Image(images[index])
                        .resizable()
                        .scaledToFit()
                        .tag(index)
                        .gesture(
                            MagnificationGesture()
                                .onChanged { value in
                                    withAnimation(.easeInOut(duration: 0.2)) {
                                        scale = currentScale * value
                                    }
                                }
                                .onEnded { value in
                                    withAnimation {
                                        currentScale = min(max(scale, 1.0), 3.0) // Limit the zoom scale
                                    }
                                }
                        )
                        .scaleEffect(currentScale)
                }
            }
            .tabViewStyle(PageTabViewStyle())
            .onTapGesture {
                // Dismiss full-screen view on tap
                currentPage = 0
            }
        }
        .navigationBarHidden(true)
    }
}

2      

You are getting the warning because you are using NavigationView in your code. In iOS 16 Apple revamped SwiftUI navigation by creating NavigationStack and NavigationSplitView. The navigation revamp deprecated NavigationView.

To get rid of the warning, you must replace NavigationView in your code with either NavigationStack or NavigationSplitView. But if you make this change, your app won't work on iOS 15 and below. If you need your code to run on earlier iOS versions, stick with NavigationView and ignore the warning.

3      

@Obelix,

Thanks, I did it.

@SwiftDevJournal, I tried to find examples for that kind of change, but they were too basic. Nothing with an image gallery like I need.

2      

What happens if you replace NavigationView with NavigationStack and keep the rest of the code?

Apple provides a guide for converting NavigationView code to NavigationStack or NavigationSplitView.

https://developer.apple.com/documentation/swiftui/migrating-to-new-navigation-types

2      

I fixed it, but it was quite a challenge and still don't know what's happening behind those lines :)

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.