Asked  4 Months ago    Answers:  5   Viewed   2k times

I have a SwiftUI app that I want to maintain iOS 13 support for, but on iOS 14 I want to use the new LazyVStack and LazyHStack. I was thinking typealias would be perfect for this, but wasn't sure how to properly set this up so the alias is used on iOS 13 but not on 14. I tried this, but believe this would make the alias available on iOS 13 and up, so would include it on iOS 14 too.

Is there a way to set the availability to iOS 13 only? Or is there a better way to do this?

@available(iOS 13.0, *)
typealias LazyVStack = VStack

 Answers

56

Here is possible wrapper that can be used as regular stack container

struct CompatibleVStack<Content> : View where Content : View {
    let alignment: HorizontalAlignment
    let spacing: CGFloat?
    let content: () -> Content

    init(alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil,
            @ViewBuilder content: @escaping () -> Content) {
        self.alignment = alignment
        self.spacing = spacing
        self.content = content
    }

    var body: some View {
      Group {
        if #available(iOS 14, *) { // << add more platforms if needed
            LazyVStack(alignment: alignment, spacing: spacing, pinnedViews: [], content:content)
        } else {
            VStack(alignment: alignment, spacing: spacing, content:content)
        }
      }
    }
}
Friday, August 27, 2021
 
Benji
answered 4 Months ago
98

Problem

It looks like the default styles of a List or NavigationView in iOS 14 may in some cases be different than in iOS 13.

Solution #1 - explicit listStyle

It's no longer always the PlainListStyle (as in iOS 13) but sometimes the InsetGroupedListStyle as well.

You need to explicitly specify the listStyle to PlainListStyle:

.listStyle(PlainListStyle())

Example:

struct ContentView: View {
    var views = ["Line 1", "Line 2", "Line 3"]

    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(views, id: .self) { view in
                        VStack {
                            Text("(view)")
                        }
                        .background(Color.red)
                    }
                }
                .listStyle(PlainListStyle()) // <- add here
            }
        }
    }
}

Solution #2 - explicit navigationViewStyle

It looks like the NavigationView's default style can sometimes be the DoubleColumnNavigationViewStyle (even on iPhones).

You can try setting the navigationViewStyle to the StackNavigationViewStyle (as in iOS 13):

.navigationViewStyle(StackNavigationViewStyle())

Example:

struct ContentView: View {
    var views = ["Line 1", "Line 2", "Line 3"]

    var body: some View {
        NavigationView {
            VStack {
                List {
                    ForEach(views, id: .self) { view in
                        VStack {
                            Text("(view)")
                        }
                        .background(Color.red)
                    }
                }
            }
        }
        .navigationViewStyle(StackNavigationViewStyle()) // <- add here
    }
}
Monday, June 7, 2021
 
samayo
answered 6 Months ago
23

The possible workaround solution can be based on TabBarAccessor from my answer on Programmatically detect Tab Bar or TabView height in SwiftUI

Here is a required modification in tab item holding NavigationView. Tested with Xcode 11.4 / iOS 13.4

demo

struct FirstTabView: View {
    @State private var tabBar: UITabBar! = nil

    var body: some View {
        NavigationView {
            NavigationLink(destination:
                FirstChildView()
                    .onAppear { self.tabBar.isHidden = true }     // !!
                    .onDisappear { self.tabBar.isHidden = false } // !!
            ) {
                Text("Go to...")
            }
            .navigationBarTitle("FirstTitle", displayMode: .inline)
        }
        .background(TabBarAccessor { tabbar in   // << here !!
            self.tabBar = tabbar
        })
    }
}

Note: or course if FirstTabView should be reusable and can be instantiated standalone, then tabBar property inside should be made optional and handle ansbsent tabBar explicitly.

Wednesday, June 9, 2021
 
uiroshan
answered 6 Months ago
76

The "Last compatible version" setting only applies to existing customers; i.e. People who have already purchased/downloaded your app.

They are able to continue to access the older version on devices that are not compatible with your latest version.

People who have never purchased your app before just won't see it in the store if their device isn't compatible.

If you release a version that requires iOS 13, your new customers will be running iOS 13 or later.

For reference, the last compatible version setting is described in the App Store Connect help (Emphasis mine)

The versions of an app that are available for existing customers to download from iCloud. You need to exclude app versions from iCloud if the version includes legal or usability issues.

Saturday, August 28, 2021
 
Astravagrant
answered 3 Months ago
78
  1. Swift 3.0 is being deprecated by Apple, you will need to use at least 4.0 from April 2020

  2. Yes, exactly as with the Swift version you can target an older version of iOS with the latest Xcode.

  3. You can only target 13 and up for those features as the APIs are not included in any older version.

Tuesday, November 30, 2021
 
Nenad Dordevic
answered 4 Days ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share