Change The 2Nd and 3Rd Pickerview Acording to What Row from The 1St Picker Is Selected

Change the 2nd and 3rd pickerView acording to what row from the 1st picker is selected

The following is the working code. It is certainly not the pretty way to do the work but will give an idea to resolve the issue.

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

@IBOutlet weak var textField_0: UITextField!
@IBOutlet weak var textField_1: UITextField!
@IBOutlet weak var textField_2: UITextField!

private var pickerGeneral1 = ["Length", "Volume", "Mass"]

// Maintaining the other arrays as single array of arrays for efficient loading
private var subContentArray = [["Millimeter", "Centimeter", "Meter", "Kilometer", "Foot", "Yard", "Mile"],
["Milliliter", "Centiliter", "Liter", "Gallon", "Quart", "Pint", "Fluid ounce"],
["Milligram", "Centigram", "Gram", "Kilogram", "Stone", "Pound", "Ounce"]]

var picker_0 = UIPickerView()
var picker_1 = UIPickerView()
var picker_2 = UIPickerView()

// To keep track of user's current selection from the main content array
private var _currentSelection: Int = 0

// whenever current selection is modified, we need to reload other pickers as their content depends upon the current selection index only.
var currentSelection: Int {
get {
return _currentSelection
}
set {
_currentSelection = newValue
picker_1 .reloadAllComponents()
picker_2 .reloadAllComponents()

textField_0.text = pickerGeneral1[_currentSelection]
textField_1.text = subContentArray[_currentSelection][0]
textField_2.text = subContentArray[_currentSelection][0]
}
}

override func viewDidLoad() {
super.viewDidLoad()

currentSelection = 0;

picker_0.delegate = self
picker_0.dataSource = self
picker_0.tag = 0

picker_1.delegate = self
picker_1.dataSource = self
picker_1.tag = 1

picker_2.delegate = self
picker_2.dataSource = self
picker_2.tag = 2

textField_0.inputView = picker_0
textField_1.inputView = picker_1
textField_2.inputView = picker_2
}

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView.tag == 0 {
return pickerGeneral1.count
} else {
return subContentArray[currentSelection].count
}
}

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView.tag == 0 {
return pickerGeneral1[row]
} else {
return subContentArray[currentSelection][row]
}
}

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView.tag == 0 {
currentSelection = row

textField_0.text = pickerGeneral1[row]
textField_0.resignFirstResponder()
} else if pickerView.tag == 1 {
textField_1.text = subContentArray[currentSelection][row]
textField_1.resignFirstResponder()
} else if pickerView.tag == 2 {
textField_2.text = subContentArray[currentSelection][row]
textField_2.resignFirstResponder()
}
}
}

I would be using only one UIPickerView instead of 3.

Swift UIPickerView 1st component changes 2nd components data

You need to reorganize a bit to make this work better and to have easier code.

The following would be one solution:

let categories = ["Attractions & Entertainment", "Eating & Drinking", "Education", "Emergency", "Financial Institution", "Lodging Establishment", "Medical & Health", "Place of Worship", "Professional Service", "Public Services & Buildings", "Service", "Stores & Shopping", "Transportation"]
let attrationsAndEntertainment = ["Amusement Center", "Amusement Park", "Art Gallery", "Art Museum", "Bowling Alley", "Community Center", "Event Venue", "Golf Club", "Golf Course", "Live Music Venue", "Movie Theater", "Museum", "National Park", "Night Club", "Park", "Performing Arts Theater", "Stadium", "Theme Park", "Tourist Attraction", "Water Park", "Winery", "Zoo", "Cinema", "Park And Garden"]
let eatingAndDrinking = ["American Restaurant", "Asian Restaurant", "Bakery", "Bar", "Bar & Grill", "Barbecue Restaurant", "Breakfast Restaurant", "Buffet Restaurant", "Café", "Chicken Restaurant", "Coffee Shop", "Deli", "Diner", "Family Restaurant", "Fast Food Restaurant", "French Restaurant", "Hamburger Restaurant", "Ice Cream Shop", "Indian Restaurant", "Italian Restaurant", "Japanese Restaurant", "Korean Restaurant", "Meal Takeaway", "Mexican Restaurant", "Pizza Delivery", "Pizza Restaurant", "Pub", "Ramen Restaurant", "Restaurant", "Sandwich Shop", "Seafood Restaurant", "Sports Bar", "Steak House", "Sushi Restaurant", "Tea House", "Thai Restaurant"]
let education = ["College", "Community College", "Elementary School","Middle School", "High School", "Kindergarten", "Preschool","Primary School", "Private School", "Public School", "Public University", "School", "Tutoring Service", "University"]
let emergency = ["Fire Station", "Police Department", "Police Station"]
let financialInstitution = ["ATM", "Accountant", "Bank", "Credit Union", "Financial Consultant", "Financial Planner", "Insurance Agency","Loan Agency", "Money Transfer Service", "Savings Bank", "Tax Consultant", "Tax Preparation Service"]
let lodgingEstablishment = ["Beach Resort", "Bed & Breakfast", "Budget Hotel", "Campground", "Extended Hotel Stay", "Guest House", "Hostel", "Hotel", "Luxury Hotel", "Motel", "RV Park", "Resort"]
let medicalAndHealth = ["Animal Hospital", "Chiropractor", "Dental Clinic", "Dentist", "Dermatologist", "Doctor", "Eye Care Center", "Family Practice Physician", "General Practitioner", "Home Health Care Services", "Hospital", "Internist", "Medical Center", "Medical Clinic", "Medical Laboratory", "Nursing Agency", "Obstetrician - Gynecologist", "Optometrist", "Pediatrician", "Physical Therapist", "Psychologist", "Veterinarian"]
let placeOfWorship = ["Ashram", "Bahai House of Worship", "Baptist Church", "Buddhist Temple", "Catholic Church", "Church", "Convent", "Gurudwara", "Hindu Temple", "Jain Temple", "Mission", "Monastery", "Mosque", "Pagoda", "Pilgrimage Place", "Place Of Worship", "Religious Destination", "Shinto Shrine", "Synagogue"]
let professionalService = ["Air Conditioning Contractor", "Architect", "Business Management Consultant", "Computer Consultant", "Consultant", "Contractor", "Engineer", "Engineering Consultant", "Internet Marketing Service", "Landscaper", "Lawyer", "Legal Services", "Notary Public", "Software Company", "Website Designer"]
let publicServicesAndBuildings = ["Apartment Building", "Apartment Complex", "Cemetery", "City Government Office", "City or Town Hall", "Condominium Complex", "County Government Office", "Department of Motor Vehicles", "Electric Utility Company", "Government Office", "Idustrial Area", "Library", "Local Government Office", "Public Library"]
let service = ["Advertising Agency", "Auto Body Shop", "Auto Repair Shop", "Barber Shop", "Beauty Salon", "Cabinet Maker", "Cable Company", "Car Repair and Maintenance", "Car Wash", "Caterer", "Cleaning Service", "Commerical Printer", "Computer Repair Service", "Construction Company", "Courier Service", "Dance School", "Day Care Center", "Dry Cleaner", "Electrician", "Employement Agency", "Event Planner", "Freight Forwarding Service", "Funeral Home", "General Contractor", "Gym", "Hair Salon", "Health Club", "Home Builder", "House Cleaning Service", "Interior Designer", "Internet Service Provider", "Laundry Service", "Marketing Agency", "Massage Therapist", "Movie Rental Kiosk", "Nail Salon", "Newspaper Publisher", "Painter", "Pest Control Service", "Photographer", "Plumber", "Post Office", "Property Management Company", "Public Swimming Pool", "Publisher", "Real Estate Agency", "Real Estate Agents", "Real Estate Developer", "Roofing Contractor", "Shipping Company", "Shipping and Mailing Service", "Spa", "Tailor", "Telecommunications Service Provider", "Tire Shop", "Tourist Information Center", "Travel Agency", "Trucking Company"]
let storesAndShopping = ["Appliance Store", "Auto Parts Store", "Baby Store", "Beauty Supply Store", "Bicycle Store", "Book Store", "Boutique", "Bridal Shop", "Building Materials Store", "Butcher Shop", "Car Dealer", "Cell Phone Store", "Childrens Clothing Store", "Clothing Store", "Coffee Store", "Computer Store", "Convenience Store", "Cosmetics Store", "Craft Store", "Department Store", "Dessert Shop", "Discount Store", "Discount Supermarket", "Donut Shop", "Drug Store", "Electrical Supply Store", "Electronics Store", "Fabric Store", "Fashion Accessories Store", "Florist", "Furniture Store", "General Store", "Gift Shop", "Grocery Store", "Hardware Store", "Health Food Store", "Home Goods Store", "Home Improvement Store", "Jeweler", "Jewelry Store", "Lingerie Store", "Liquor Store", "Lottery Retailer", "Market", "Men's Clothing Store", "Motorcycle Dealer", "Office Supply Store", "Optician", "Outdoor Sports Store", "Outlet Mall", "Paint Store", "Pawn Shop", "Pet Store", "Pet Supply Store", "Pharmacy", "Print Shop", "Shoe Store", "Shopping Mall", "Sporting Goods Store", "Sportswear Store", "Stationery Store", "Store", "Supermarket", "Tattoo Shop", "Toy Store", "User Car Dealer", "Video Game Store", "Warehouse Club", "Wine Store", "Women's Clothing Store"]
let transportation = ["Car Rental Agency", "Driving School", "Gas Station", "Parking Garage", "Parking Lot", "Taxi Service", "Transportation Service", "Truck Rental Agency"]

var secondColumnData = [[String]]()

override func viewDidLoad() {
super.viewDidLoad()

secondColumnData = [attrationsAndEntertainment, eatingAndDrinking, education, emergency, financialInstitution, lodgingEstablishment, medicalAndHealth, placeOfWorship, professionalService, publicServicesAndBuildings, service, storesAndShopping, transportation]

pickerView.delegate = self
pickerView.dataSource = self
pickerView.reloadAllComponents()
pickerView.selectRow(0, inComponent: 0, animated: false)
}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 2
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return categories.count
} else {
let selected = pickerView.selectedRow(inComponent: 0)

return secondColumnData[selected].count
}
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return categories[row]
} else {
let selected = pickerView.selectedRow(inComponent: 0)

return secondColumnData[selected][row]
}
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if component == 0 {
pickerView.reloadComponent(1)
} else {
let selected = pickerView.selectedRow(inComponent: 0)

someTextField.text = secondColumnData[selected][row]
}
}

An even better solution is to take all of that data out of your code and put it all in a plist file in your app's bundle. Make the plist an array of dictionary. Each dictionary would have a category title (which will be shown in the 1st component of the picker), and the array of values for that category (shown in the 2nd component).

The code to support this data structure would be similar to the code above.

Displaying second column in UIPickerView from JSON using what is picked from first column

class TestViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

struct Category {
var name: String
var items: [String]
}
var allCategories = [Category]()
var selectedCategory:Category?
var selectedItem: String?

var pickerView: UIPickerView!

override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
allCategories = [Category(name: "Fruits", items: ["Apple","Banana"]), Category(name: "Vegetables", items: ["Cucumber","Potato"])]
pickerView = UIPickerView(frame: CGRect(x: 0, y: 200, width: UIScreen.main.bounds.width, height: 200))
view.addSubview(pickerView)
pickerView.dataSource = self
pickerView.delegate = self

}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return selectedCategory == nil ? 1 : 2
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return component == 0 ? allCategories.count : selectedCategory?.items.count ?? 0
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == 0 {
return allCategories[row].name
} else {
return selectedCategory?.items[row]
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if component == 0 {
selectedCategory = allCategories[row]
manufacturerTextField.text = allCategories[row].name
pickerView.reloadAllComponents()
} else {
selectedItem = selectedCategory?.items[row]
modelTextField.text = selectedCategory?.items[row]
}
}

}

Edit

if let url = URL(string: "https://www.example.com/test/test.php"),
let data = try? Data(contentsOf: url),
let tmpValues = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [[String:String]] {
let tempCategories = tmpValues?.reduce(into: [String:[String]](), { (dict, value) in
if let manufacturer = value["manufacturer"], let model = value["model"] {
dict[manufacturer, default:[]].append(model)
}
})
for category in (tempCategories ?? [:]) {
allCategories.append(Category(name: category.key, items: category.value))
}
pickerView.reloadAllComponents()
}

Sample Image

How can I populate a picker view depending on the selection of another picker view in Swift?

As both the Pickers are using the same delegate you are going to need a way to identify them when your delegate methods run, also your current Array structure means you are going to need a way to select each item array as and when the country is selected.

Create a store for the selected item array.

var selectedItemsArray = []

Add some checks to your delegate methods.

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == countryPicker {
return countryClasses.count
} else if pickerView == itemPicker {
return selectedItemsArray.count
}
return 0
}

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
if pickerView == countryPicker {
return countryClasses[row]
} else if pickerView == itemPicker {
return selectedItemsArray[row]
}
return 0
}

Then you need to implement did Select row to setup the item store and reload the data.

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == countryPicker {
switch row {
case 0:
selectedItemsArray = usItems
case 1:
selectedItemsArray = euItems
case 2:
selectedItemsArray = jpItems
default:
selectedItemsArray = []
}
// IMPORTANT reload the data on the item picker
itemPicker.reloadAllComponents()
} else if pickerView == itemPicker {
// Get the current item
var item = selectedItemsArray[row]
// Assign value to a label based on which array we are using
if selectedItemsArray == usItems {
usLabel.text = item
} else if selectedItemsArray == euItems {
euLabel.text = item
} else if selectedItemsArray == jpItems {
jpLabel.text = item
}
}
}

I haven't tested this code, but the logic should be correct.

Change Label According to UIPickerView's Selected Row in If Statement

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

if pickerView.tag == 1 {
categoryOutput.text = category[row] }
if pickerView.tag == 2 {
shapeOutput.text = shape[row]

if row == 1 //Circle{
dimensionLabel.text = "Diameter" }
else {
dimensionLabel.text = "Length" }
}
}

UIPICKERVIEW with different data to be displayed according to the row selected

You need to set the textfield text

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

if (pickerView == leaguepickerview_destination) {
x = row
clubpickerview_denomination.reloadAllComponents()
textfield1.text = league_destination[row]
}
else {
textfield2.text = club_denomination[x][row]
}
}


Related Topics



Leave a reply



Submit