简体   繁体   中英

UIPickerView delegate not called in a subview

I have a simple iOS app that uses UISegmentedControl to switch between two tabs.

In ViewController.swift:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var segment: UISegmentedControl!
    @IBOutlet weak var viewContainer: UIView!
    var searchView: UIView!
    var favView: UIView!

override func viewDidLoad() {
    super.viewDidLoad()
    searchView = SearchViewController().view
    favView = FavoriteViewController().view
    viewContainer.addSubview(favView)
    viewContainer.addSubview(searchView)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

@IBAction func segmentChange(_ sender: UISegmentedControl) {
    switch sender.selectedSegmentIndex{
    case 0:
        viewContainer.bringSubview(toFront: searchView)
        break
    case 1:
        viewContainer.bringSubview(toFront: favView)
        break
    default:
        break
    }
}
}

And in the first tab, I have a UIPickerView as input of a Textfield.

import UIKit

class SearchViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var keywordField: UITextField!
    @IBOutlet weak var categoryField: UITextField!
    @IBOutlet weak var distanceField: UITextField!
    @IBOutlet weak var locationField: UITextField!

    var cgpicker = UIPickerView()
    let categories = ["Default", "Airport", "Amusement Park", "Aquarium", "Art Gallery", "Bakery", "Bar"]

override func viewDidLoad() {
    super.viewDidLoad()
    cgpicker.delegate = self
    cgpicker.dataSource = self
    categoryField.inputView = cgpicker
    categoryField.text = categories[0]
}

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

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    print("picker working")
    return categories.count
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return categories[row]
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    categoryField.text = categories[row]
    categoryField.resignFirstResponder()
}

}

However, when I click the Textfield, the PickerView doesn't display data. In fact the delegate and datasource is not called since the "print" is never called. However the same code is working fine in a simple UIView app. I cannot find any solution related to this problem.

UIPickerView not showing data

The problem is with the viewDidLoad of your ViewController class.

You are not creating the container view controller properly. The primary issue preventing the picker from working is that your SearchViewController has no strong reference to it when viewDidLoad finishes so the picker in SearchViewController becomes nil .

Update the ViewController viewDidLoad to something like this:

override func viewDidLoad() {
    super.viewDidLoad()

    let searchVC = SearchViewController()
    searchView = searchVC.view
    addChildViewController(searchVC)
    // Should set searchView frame or constraints
    viewContainer.addSubview(searchView)
    searchVC.didMove(toParentViewController: self)

    let favVC = FavoriteViewController()
    favView = favVC.view
    addChildViewController(favVC)
    // Should set favView frame or constraints
    viewContainer.addSubview(favView)
    favVC.didMove(toParentViewController: self)
}

This because you not load picker

you should have reference to SearchViewController not reference to its View

ViewController:

class ViewController: UIViewController {

    @IBOutlet weak var segment: UISegmentedControl!
    @IBOutlet weak var viewContainer: UIView!
    var searchController: SearchViewController!
    var favController: FavoriteViewController!

    override func viewDidLoad() {
        super.viewDidLoad()
        searchController = SearchViewController()
        favController = FavoriteViewController()
        viewContainer.addSubview(searchController.view)
        viewContainer.addSubview(favController.view)
        searchController.loadPickerView()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }


    @IBAction func segmentChange(_ sender: UISegmentedControl) {
        switch sender.selectedSegmentIndex{
        case 0:
            viewContainer.bringSubview(toFront: searchController.view)
             searchController.loadPickerView()
            break
        case 1:
            viewContainer.bringSubview(toFront: favController.view)
            break
        default:
            break
        }
    }
}

Add loadPickerView func to SearchViewController

 func loadPickerView() {
        cgpicker.delegate = self
        cgpicker.dataSource = self
        self.textFieldUserName.inputView = cgpicker
        textFieldUserName.text = categories[0]
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM