filipealva / PickerView

🔸 A customizable alternative to UIPickerView in Swift.
MIT License
527 stars 92 forks source link

Programmatically Select Row #24

Closed dhruveonmars closed 6 years ago

dhruveonmars commented 7 years ago

Is there a way to programmatically scroll to a row or index, after the picker has loaded? I need to scroll to specific items, after the view has loaded, based on what the user selects in that View Controller

I've tried objectPicker.currentSelectedRow = 0

Any help is appreciated.

filipealva commented 7 years ago

Hi @DhruveShah

In order to do that you should call the selectRow(_ row : Int, animated: Bool) method.

dhruveonmars commented 7 years ago

@filipealva Thanks for the help. That works, however, it is changing my infinite PickerView to the default behaviour, and trying to change the style after calling selectRow does not seem to make a difference.

filipealva commented 7 years ago

@DhruveShah it should not behave like that. I've used this method in a lot of projects and any of them had this issue (I just tried to reproduce it on some of them right now).

Can you provide a sample project that reproduces this issue?

tks

dhruveonmars commented 7 years ago

One thing I just noticed, if you scroll down it appears as infinite list and is fine, however if you scroll up, it doesn't appear to be an infinite list and stops at the first item.

So for example, calling selectRow(0, true), scrolls to the top, with no items appearing before that, but scrolling down however, makes it appear as an infinite list.

I'm not sure if this is due to the list size being rather small (15 items)

I will be sure to upload a sample project or code first thing in the morning.

dhruveonmars commented 7 years ago

@filipealva This is essentially what my code is doing:

@IBOutlet weak var locationSelector: PickerView!

The following is inside my class:

override func viewDidLoad() {
        super.viewDidLoad()
        configurePicker()
}

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        locationAuthStatus()
}

fileprivate func configurePicker() {
        locationSelector.dataSource = self
        locationSelector.delegate = self

        let scrollingStyle: PickerView.ScrollingStyle
        let selectionStyle: PickerView.SelectionStyle

        scrollingStyle = PickerView.ScrollingStyle.infinite
        selectionStyle = PickerView.SelectionStyle.defaultIndicator

        locationSelector.scrollingStyle = scrollingStyle
        locationSelector.selectionStyle = selectionStyle
}

func locationAuthStatus() {
        if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
            currentLocation = locationManager.location

            let exampleLocation = CLLocation(latitude: 48.770344, longitude: 9.171880)

            geocoder.reverseGeocodeLocation(exampleLocation) { (placemarks, error) in
                // Process Response
                self.processResponse(withPlacemarks: placemarks, error: error)
            }
        } else {
            locationManager.requestWhenInUseAuthorization()
            locationAuthStatus()
        }
}

private func processResponse(withPlacemarks placemarks: [CLPlacemark]?, error: Error?) {
        if let error = error {
            print("Unable to Reverse Geocode Location (\(error))")
        } else {
            if let placemarks = placemarks, let placemark = placemarks.first {
                stateSelected = placemark.administrativeArea!
                userCountry = placemark.country
                print(placemark.administrativeArea!)
                locationSelector.selectRow(0, animated: true)
            } else {
                print("No Matching Addresses Found")
            }
        }
}

And then I have the delegate and data source set up after:

extension SetLocationVC: PickerViewDataSource {
    func pickerViewNumberOfRows(_ pickerView: PickerView) -> Int {
        return DataView.states.count
    }

    func pickerView(_ pickerView: PickerView, titleForRow row: Int, index: Int) -> String {
        return DataView.states[index].stateName
    }
}

extension SetLocationVC: PickerViewDelegate {
    func pickerViewHeightForRows(_ pickerView: PickerView) -> CGFloat {
        return 50.0
    }

    func pickerView(_ pickerView: PickerView, didSelectRow row: Int, index: Int) {
        print(index)
        print(DataView.states[index].stateName)
    }

    func pickerView(_ pickerView: PickerView, styleForLabel label: UILabel, highlighted: Bool) {
        DataView.pickerStyle(label: label, highlighted: highlighted)
    }
}

What I'm doing is requesting the users location, and then wanting to select that index

filipealva commented 6 years ago

@DhruveShah hey, sorry about the delay.

I could found the issue it was a bug on PickerView.

Just fixed it. I know it has been a long time, but if you could test it would be awesome. Just points to this branch https://github.com/filipealva/PickerView/tree/fix/select-row-issues in your Podfile.