SALE: Save 50% on all my books and bundles >>

Creating Pickers in a form

Forums > SwiftUI

Hello all (and Paul !),

Thanks for this great ressource on SwiftUI, I'm just starting out, but this looks awesome.

I'm a bit stumped on the WeSplit Tutorial 8/10 :

The picker does not seem to behave the way it should, or at least the way Paul describes it. Despite adding the NavigationView, I still see the disclosure arrow and taping on the picker does nothing...

Here is my code :

struct ContentView: View {

    @State private var checkAmount = ""
    @State private var numberOfPeople = 2
    @State private var tipPercentage = 2
    let tipPercentages = [10, 15, 20, 25, 0]

      var body: some View {
        NavigationView {
            Form {
                         Section {
                             TextField("Amount", text: $checkAmount)
                               .keyboardType(.decimalPad)

                           Picker("Number of people", selection: $numberOfPeople) {
                           ForEach(2 ..< 100) { number in
                               Text("\(number) people")
                               }
                           }
                         }

                         Section {
                             Text("$\(checkAmount)")
                                }
                    }
        }
    }
}

Any ideas ?

thanks

   

I ran this snippet and I was able to click on "Number of people" and modify the value from the screen that was pushed onto the navigation stack.

I've noticed some issues with preview not working correctly in Xcode with Swift UI, or having to press the "Play" button to get interactivity. Might just be an Xcode bug, so try running it on the device.

   

Thanks for the reply Peter,

When running on my device, at first, it seemed like it still was not working. After a few more tries, it turns out I need to LONG-tap on the picker in order to make the other view appear. And on that new view, I also need to long-tap on a selection before the app returns to the main screen, and in doing so, I get the following log message :

2020-03-24 07:52:02.147566+0100 WeSplit[11301:3064341] [TableView] Warning once only: UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window). This may cause bugs by forcing views inside the table view to load and perform layout without accurate information (e.g. table view bounds, trait collection, layout margins, safe area insets, etc), and will also cause unnecessary performance overhead due to extra layout passes. Make a symbolic breakpoint at UITableViewAlertForLayoutOutsideViewHierarchy to catch this in the debugger and see what caused this to occur, so you can avoid this action altogether if possible, or defer it until the table view has been added to a window. Table view: <_TtC7SwiftUIP33_BFB370BA5F1BADDC9D83021565761A4925UpdateCoalescingTableView: 0x10c854c00; baseClass = UITableView; frame = (0 0; 375 812); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x282534660>; layer = <CALayer: 0x282baf9e0>; contentOffset: {0, -140}; contentSize: {375, 4449.3333333333285}; adjustedContentInset: {140, 0, 34, 0}; dataSource: <_TtGC7SwiftUIP10$1bd7e92b419ListCoreCoordinatorGVS_20SystemListDataSourceOs5Never_GOS_19SelectionManagerBoxS2___: 0x10bd1c560>>

Also, the blue " < WeSplit" button on the picker view does not work.

When I enter an amount, I get these 2 similar messages when I tap (once) on the textField and summon the keyboard :

2020-03-24 07:57:43.115049+0100 WeSplit[11310:3066812] Can't find keyplane that supports type 8 for keyboard iPhone-PortraitChoco-DecimalPad; using 25727_PortraitChoco_iPhone-Simple-Pad_Default 2020-03-24 07:57:43.185505+0100 WeSplit[11310:3066812] Can't find keyplane that supports type 8 for keyboard iPhone-PortraitChoco-DecimalPad; using 25727_PortraitChoco_iPhone-Simple-Pad_Default

And this message every time I tap on a key from the displayed keyboard :

ForEach<Range<Int>, Int, Text> count (98) != its initial count (1). ForEach(_:content:) should only be used for constant data. Instead conform data to Identifiable or use ForEach(_:id:content:) and provide an explicit id!

Anyone else has the same issue ?

   

@Esowes is there additional code you could provide? Or could you drop a link to the WeSplit project description if it's publicly available?

   

Hey Peter,

That's the whole ContentView code :

import SwiftUI

struct ContentView: View {

    @State private var checkAmount = ""
    @State private var numberOfPeople = 0
    @State private var tipPercentage = 2
    let tipPercentages = [10, 15, 20, 25, 0]

      var body: some View {
        NavigationView {
            Form {
                         Section {
                             TextField("Amount", text: $checkAmount)
                               .keyboardType(.decimalPad)
                                .textFieldStyle(RoundedBorderTextFieldStyle())

                           Picker("Number of people", selection: $numberOfPeople) {
                           ForEach(2 ..< 100) { number in
                               Text("\(number) people")
                               }
                           }
                         }

                         Section {
                             Text("$\(checkAmount)")
                                }
                    }
        .navigationBarTitle("WeSplit")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

And I just modified the SceneDelegate like so (added the .onTapGesture bit), in order to be able to dismiss the keyboard by tapping outside it :

if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView.onTapGesture { window.endEditing(true)})
            self.window = window
            window.makeKeyAndVisible()
        }
    }

   

@Esowes, I was able to reproduce the error message

ForEach<Range<Int>, Int, Text> count (98) != its initial count (1). ForEach(:content:) should only be used for constant data. Instead conform data to Identifiable or use ForEach(:id:content:) and provide an explicit id!

Take a look at Paul's article here, it'll explain why you're getting that error, and how to resolve it. https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-views-in-a-loop-using-foreach

With regards to your Picker not working, set a breakpoint on window.endEditing(true) in SceneDelegate. You'll notice that it's being hit, my guess is it's intercepting your tap on the Picker. This might be helpful: https://stackoverflow.com/questions/56491386/how-to-hide-keyboard-when-using-swiftui

   

Hacking with Swift is sponsored by RevenueCat

SPONSORED Building in-app subscriptions are hard. RevenueCat makes it simple. With their open source SDKs, you can painlessly implement subscriptions for your app in hours, not months.

Explore the docs to learn more

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.

Cascable unleashes the power of your camera and unlocks powerful workflows for shooting, managing, and geotagging your photos.

 
Unknown user

Not logged in

Log in