Hot questions for Using Eureka in swift4

Question:

When I expand the PickerInlineRow, I want to be able to select the first option. For cases where there is only one option, I cannot call the onChange method so it can never be picked.


Answer:

This is a hack.. But I select the first row by setting the row value = the first element in the array on the network callback.

  if let row = self.form.rowBy(tag: "Row") as? PickerInlineRow<RowType> {
    row.value = rowTypes.first
    row.reload()
  }

Question:

I'm using a Eureka form, in which the user selects dates. When the user selects the first date, I want to update the second date in the second row (add 30 days to the first days).

        <<< DateRow(){
            $0.value = Date()
            $0.title = "First Date"
            $0.tag = "firstDate"
            .onChange({ (row) in
                << update secondDate = firstDate + 30 days >>
            } )

         <<< DateRow(){
            $0.value = Date()
            $0.title = "Second Date"
            $0.tag = "secondDate"

How can I achieve that?


Answer:

Please find below solution.

func createSection() {
    let section = Section("Section2") { section in
        section.header?.height = { 40 }
    }

    <<< DateRow() {
        $0.value = Date()
        $0.title = "First Date"
        $0.tag = "First"
        }.onChange({ (row) in
            let secondRow = self.form.rowBy(tag: "Second") as! DateRow
            let date = row.value!
            let newDate = date.addingTimeInterval(30*24*60*60)
            secondRow.value = newDate
            secondRow.reload()
        })

    <<< DateRow() {
        $0.value = Date()
        $0.title = "Second Date"
        $0.tag = "Second"
        }.onChange({ (row) in

        })

    form +++ section
}

Let me know in case of any queries.

Question:

I use xCode 9, swift 4 and "Eureka form library" for my project.

The situation

I have a list of cars with name and unique ID associated this way: 0 - ANY, 1 - VW, 7 - AUDI, 20 - MAZDA

var name_cars: [String] = ["ANY","VW","AUDI","MAZDA"]

var id_cars:[Int] = [0, 1, 7, 20]

I also have a form with "PushRow" and "ButtonRow". On click to the button I want to print the selected car name and ID. I was able to print the car's name but not the ID.

import UIKit
import Eureka

class myPage: FormViewController {

    var cars: [String] = ["ANY","VW","AUDI","MAZDA"]
    var id_cars:[Int] = [0, 1,7,20]

    var selected_car: String = "ANY" //default car
    var selected_car_id: Int = 0 //default id car

    override func viewDidLoad() {
        super.viewDidLoad()

        create_form()
    }

    func create_form(){

        form
        +++ Section("List")

        //list
        <<< PushRow<String>() {
            $0.title = "Cars"
            $0.options = cars
            $0.value = "ANY"

            $0.tag = "list_element"
            $0.selectorTitle = "Choose car"
            $0.onChange { [unowned self] row in
                self.selected_car = row.value!
                self.selected_car_id = ??? // **what should it be here in order to get the ID**
            }

        }

        //button
        <<< ButtonRow("Button1") {row in
            row.title = "Get Value on Console"
            row.onCellSelection{[unowned self] ButtonCellOf, row in
                print ("Car selected = ",self.selected_car, " and Id_Car_Selected = ",self.selected_car_id)
            }
        }
   }
}

Answer:

First of all please conform to the naming convention that class names start with a capital letter and variable names are lowerCamelCased rather than snake_cased.

Swift is an object oriented language. Rather than two separate arrays use a custom struct Car.

import UIKit
import Eureka

struct Car : Equatable {
    let name : String
    let id : Int
}

The push row is declared as PushRow<Car>() and the property displayValueFor is populated with the name

class MyPage: FormViewController {

    let cars = [Car(name: "ANY", id: 0), Car(name: "VW", id: 1), Car(name: "AUDI", id: 7), Car(name: "MAZDA", id: 20)]

    var selectedCar : Car!

    override func viewDidLoad() {
        super.viewDidLoad()
        selectedCar = cars[0]
        createForm()
    }


    func createForm() {

        form
            +++ Section("List")

            //list
            <<< PushRow<Car>() {
                $0.title = "Cars"
                $0.options = cars
                $0.value = selectedCar
                $0.displayValueFor = {
                    guard let car = $0 else { return nil }
                    return car.name
                }

                $0.tag = "list_element"
                $0.selectorTitle = "Choose car"
                $0.onChange { [unowned self] row in
                    self.selectedCar = row.value!
                }

            }

            //button
            <<< ButtonRow("Button1") {row in
                row.title = "Get Value on Console"
                row.onCellSelection{[unowned self] ButtonCellOf, row in
                    print ("Car selected = ", self.selectedCar.name, " and Id_Car_Selected = ", self.selectedCar.id)
                }
        }
    }
}

Question:

I use xCode 9, Swift 4 and "Eureka form library" for my project.

The situation :

I have form with a list and a button.

I need help with these 2 issues :

  1. when click on button I want to print the selected value
  2. I want to be able to set for the list an element as a default selected value

My code :

import UIKit
import Eureka

class myPage: FormViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        createForm()
    }


    func createForm(){
        form
        +++ Section("Sample list ")
        form +++ SelectableSection<ListCheckRow<String>>("Continents", selectionType: .singleSelection(enableDeselection: false))

        let continents = ["Africa", "Antarctica", "Asia", "Australia", "Europe", "North America", "South America"]

        for element in continents {
            form.last! <<< ListCheckRow<String>(element){ listRow in
                listRow.title = element
                listRow.selectableValue = element
                listRow.value = nil
            }
        }

        form.last! <<< ButtonRow("Button1") {row in
            row.title = "Get List Value"
            row.onCellSelection{[unowned self] ButtonCellOf, row in

            print ("Selected List Value = ????????")
        }
    }
}

Thanks in advance.


Answer:

For printing all the form value:

print(form.values())

This will print the dictionary for the all form values keyed by the row tag.

For this case it prints like this (Australia is selected):

["Asia": nil, "Africa": nil, "Antarctica": nil, "Australia": Optional( "Australia"), "Europe": nil, "South America": nil, "Button1": nil, "North America": nil]

Eureka's SelectableSection also have selectedRow() (for multiple selection selectedRows()) methods.

So you can get selected values like this:

First just add tag to SelectableSection to a tag.

form +++ SelectableSection<ListCheckRow<String>>("Continents", selectionType: .singleSelection(enableDeselection: false)) { section in
   section.tag = "SelectableSection"
}

Now on the button selection

form <<< ButtonRow("Button1") { row in 
        .. // button setup
    }.onCellSelection { [unowned self] (cell, row) in
        if let section = self.form.section(by: "SelectableSection") as?
                               SelectableSection<ListCheckRow<String>> {
            print(section.selectedRow()?.value ?? "Nothing is selected") 
        }
    }

Now For Default value selection:

let defaultContinent = "Antarctica" 

Now in Button's onCellSelection:

}.onCellSelection { [unowned self] (cell, row) in
    .. // printing the selected row as above
    if let row = self.form.row(by: defaultContinent) as? ListCheckRow<String> {
       row.selectableValue = defaultContinent 
       row.didSelect()
    }
}

Question:

I've been trying to figure this one out all day and have been unsuccessful. What I'm trying to do is retrieve selected values from a multiple selector row. The row so far is fully functioning and I've been able to set it up so that my options are structs.

The problem I'm having is towards the end when I need to retrieve the data from the form. I'm able to use form.values() and know how to work with the dictionary for the most part.

When I call for the values in the multi-row, they come through as 'Sets'. I am still relatively new to Swift so I hadn't dealt with these before, but from what I've read so far they are collection types like Arrays?

this is the part that is giving me issues:

//
        <<< ButtonRow("btnnRow") { row in
            row.title = "Confirm selection."
            row.onCellSelection({ (cell, row) in
                let formValues = self.form.values()
                let koko = formValues["multiSelectTest"] as! Set<MultiTestStruct>
                switch koko.isEmpty {
                case true:
                    print("Set is empty")
                case false:
                    print("Set is NOT empty!")
                }
            })
    }

This is the latest iteration of what I've attempted. It's able to print 'empty' on first load, but as soon as I select an option and unselect it again, crash!

I think I'm having problems after selection because when I print all values, it's initially "multiSelectTest": nil, but after making a selection in the Multi-row then unselecting it, this is what it turns into: "multiSelectTest": Optional(Set([])).

Apologies if this makes no sense, I'd be happy to explain further if needed, it's currently 2am and my brain is pretty frazzled!

TL:DR - How to get values from a multiple selection row.

Thank you for reading.

Update: error message- Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value - I get this error if I try to get the rows value before selecting and unselecting. Once selection has been toggled, there is no issue.

This is the console output of all values prior to making a selection:

["btnRow": nil, "btnRow2": nil, "multiSelectTest": nil]

This is the console output after selecting an option:

["btnRow": nil, "btnRow2": nil, "multiSelectTest": Optional(Set([theDD_Admin.MultiTestStruct(name: "HELLO!")]))]

And finally, this is after I've cleared the multi-row of all options:

["btnRow": nil, "btnRow2": nil, "multiSelectTest": Optional(Set([]))]

My main plan of action was to call for the multi-row values if multi was nil but as you can see it is only nil whilst untouched. After making an option an even unselecting, it turns into a set and I get lost from there.

thanks


Answer:

From @koropok's comment, this is what I've managed to come up with. In the multi-row, I set the .onChange behaviour -

row.onChange({ (row) in
                if row.value?.isEmpty == true {
                    // if row Set<> is empty then this row will be cleared and set to nil
                    self.form.setValues(["multiSelectTest" : nil])
                }
            })

I was running into an error when I tried to do row.value = nil and this way is working as intended.

This is what I've come up with and is working well for me so far. For those with more experience than I, is this the correct/best approach? Would like to know if anyone would do anything differently.

Thanks again!