0

我是 swift 的新手,我正在想一种方法来理想地使用我以前没有尝试过的段控制来填充数据。

VC有下面的布局

  • CategoryType 段控制:控制 CategoryType)
  • CategoryTextField 具有选择器功能:键盘将显示类别中的数据列表

选择 CategoryType 段控件的预期结果以在 pickerview 上显示基于 CategoryType 的数据列表

此代码处于试错模式,因为我不知道如何执行我希望获得的结果。

 func appendDefaultCategoryTypes() {
        categories = realm.objects(Category.self)
        if categories.count == 0 {
            try! realm.write() {
                let defaultCategories = [
                    Category(type: .Expense, name: "EXPENSE 1"),
                    Category(type: .Expense, name: "EXPENSE 2"),
                    Category(type: .Income, name: "INCOME 1"),
                    Category(type: .Income, name: "INCOME 2"),

                ]
                realm.add(defaultCategories)

            }
        }
    }

//MARK: - Transaction Section
class Transaction : Object {
    //Child of Transaction
    let parentAccount = LinkingObjects(fromType: Account.self, property: "ofTransactions")

    @objc dynamic var categoryType : Category?
    @objc dynamic var amount : String = ""
    @objc dynamic var date : String = ""

}
//MARK: - Transaction Category Section

enum CategoryType : String, CaseIterable {
    case Income = "Income"
    case Expense = "Expense"

    static let allValues = [Income, Expense]

    init?(id : Int) {
        switch id {
        case 1:
            self = .Income
        case 2:
            self = .Expense
      default:
                 return nil
        }
    }

}



class Category : Object {
    @objc dynamic var type : String = CategoryType.Income.rawValue
    @objc dynamic var name : String = ""

    convenience init(type:CategoryType, name: String) {
        self.init()
        self.type = type.rawValue
        self.name = name
    }

}
//VC
    var categories : Results<Category>!

    var picker = UIPickerView()

    @IBAction func categoryTypeSC(_ sender: UISegmentedControl) {
        guard let selectedCategoryType = CategoryType.(rawValue: sender.selectedSegmentIndex) else {
            fatalError("no corresponding category type for the index selected by segment control")
        }
        switch selectedCategoryType {
        case .income :
            print("Income in SC selected")
        case .expense :
            print("Expense in SC selected")
        }

    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
//        if categorySCoutlet.selectedSegmentIndex == 0 {
//            return CategoryType.income.count
//        } else if categorySCoutlet.selectedSegmentIndex == 1 {
//            return CategoryType.expense.count
//        }
        return categories.count
    }

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
//        if categorySCoutlet.selectedSegmentIndex == 0 {
//            return
//        } else if categorySCoutlet.selectedSegmentIndex == 1 {
//            return
//        }
//        return "None"
        return categories[row].name
    }

4

1 回答 1

0

在您的视图控制器中,您需要跟踪与分段控件指示的类型相对应的类别。我称之为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()
        }
    }
}

当分段控件值更改时,您需要刷新选取器,以便内容反映所选类别类型。

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
        }
    }
}
于 2020-04-21T09:58:11.900 回答