BLACK FRIDAY: Save 50% on all my Swift 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

3      

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.

3      

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 ?

3      

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

3      

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()
        }
    }

3      

@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

3      

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.