В вашем контроллере представления вы должны отслеживать категории, которые соответствуют типу, указанному сегментированным элементом управления. Я называю это currentCategories
.
class ViewController: UIViewController {
@IBOutlet weak var segmentedControl: UISegmentedControl!
@IBOutlet weak var textField: UITextField!
var categories: Results<Category>!
var currentCategories: Results<Category>!
lazy var pickerView: UIPickerView = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
let realm = try! Realm()
categories = realm.objects(Category.self)
appendDefaultCategoryTypes()
currentCategories = categories.filter("type == %@", CategoryType.income.rawValue)
textField.text = currentCategories.first?.name
textField.inputView = pickerView
pickerView.delegate = self
pickerView.dataSource = self
segmentedControl.addTarget(self, action: #selector(onCategoryTypeChanged(_:)), for: .valueChanged)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
if touches.first?.view == view {
textField.resignFirstResponder()
}
}
}
Когда изменяется сегментированное управляющее значение, вам нужно переосмыслить sh сборщик так, чтобы содержимое отражало выбранный тип категории.
extension ViewController {
@IBAction func onCategoryTypeChanged(_ sender: UISegmentedControl) {
guard let type = CategoryType(id: sender.selectedSegmentIndex) else {
fatalError("no corresponding category type for the index selected by segment control")
}
currentCategories = categories.filter("type == %@", type.rawValue)
textField.text = currentCategories.first?.name
pickerView.reloadAllComponents()
pickerView.selectRow(0, inComponent: 0, animated: true)
}
}
В вашем источнике данных и методах делегирования вам нужно ссылаться на данные из категорий, которые отражают текущий тип.
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return currentCategories.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return currentCategories[row].name
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
textField.text = currentCategories[row].name
}
}
Обратите внимание, что я позволил себе изменить пару вещей в вашем перечислении CategoryType
. Индексы должны начинаться с нуля, а регистры должны быть в нижнем регистре.
enum CategoryType : String, CaseIterable {
case income = "income"
case expense = "expense"
init?(id : Int) {
if id < CategoryType.allCases.count {
self = CategoryType.allCases[id]
} else {
return nil
}
}
}