我将这个库用于Swift表单:https://github.com/ortuman/SwiftForms这与Eureka非常相似。
这是对我要做的事情的解释:
我的表格中有2个选择器。 Picker1只是一个普通的选择器,而Picker2依赖于Picker1的值。所以当用户更改Picker1的值时。 Picker2中的选项也应该更改。要做到这一点,这就是我的功能:
func change_data(){
row4.configuration[FormRowDescriptor.Configuration.Options] = ["hello", "from", "the"]
row4.value = "hello"
self.tableView.reloadData()
}
我使用reloadData()
查看我的2个选择器值的变化。但不幸的是,我收到错误:assertion failed: self.form property MUST be assigned!
我尝试将该代码放在顶部栏中按钮的操作中并且可以正常工作。
func submit(_: UIBarButtonItem!) {
//let message = self.form.formValues().description
//let alert: UIAlertView = UIAlertView(title: "Form output", message: message, delegate: nil, cancelButtonTitle: "OK")
//alert.show()
row4.configuration[FormRowDescriptor.Configuration.Options] = ["hello", "from", "the"]
row4.value = "hello"
self.tableView.reloadData()
}
但我需要在我的功能中调用reloadData()
,而不是按下按钮。
这是我的FormViewController的viewDidLoad:
public override func viewDidLoad() {
super.viewDidLoad()
assert(form != nil, "self.form property MUST be assigned!")
navigationItem.title = form.title
}
我有几个选择器,最后一个选择器将取决于从第2和第3选择的项目。我将这些函数称为更新我上一个选择器的内容。
这是我的FormViewController类:
import UIKit
import CoreData
import SwiftForms
class ExampleFormViewController: FormViewController {
struct Static {
static let nameTag = "name"
static let passwordTag = "password"
static let lastNameTag = "lastName"
static let jobTag = "job"
static let emailTag = "email"
static let URLTag = "url"
static let phoneTag = "phone"
static let enabled = "enabled"
static let check = "check"
static let segmented = "segmented"
static let picker = "picker"
static let birthday = "birthday"
static let categories = "categories"
static let button = "button"
static let stepper = "stepper"
static let slider = "slider"
static let textView = "textview"
}
var val_territory = [Int]()
var val_company = [Int]()
var val_facility = [Int]()
var val_specialty = [Int]()
var putu_company = ""
var putu_territory = ""
var putu_facility = ""
var str_territory = [String]()
var str_company = [String]()
var str_facility = [String]()
var str_specialty = [String]()
var territory: [Territory] = []
var company: [Company] = []
var facility: [Facility] = []
var specialty: [Specialty] = []
var row1 = FormRowDescriptor(tag: Static.picker, rowType: .Picker, title: "Territory")
var row2 = FormRowDescriptor(tag: Static.picker, rowType: .Picker, title: "Company")
var row3 = FormRowDescriptor(tag: Static.picker, rowType: .Picker, title: "Facility")
var row4 = FormRowDescriptor(tag: Static.picker, rowType: .Picker, title: "Specialty")
let name: String
var form2 = FormDescriptor(title: "Create Shift Entry")
init(_ coder: NSCoder? = nil) {
name = "Bar"
if let coder = coder {
super.init(coder: coder)
} else {
super.init(nibName: nil, bundle:nil)
}
}
required convenience init(coder: NSCoder) {
self.init(coder)
load_data()
self.loadForm()
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .Plain, target: self, action: "submit:")
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .Plain, target: self, action: "cancel:")
}
// MARK: Actions
func submit(_: UIBarButtonItem!) {
//let message = self.form.formValues().description
//let alert: UIAlertView = UIAlertView(title: "Form output", message: message, delegate: nil, cancelButtonTitle: "OK")
//alert.show()
row4.configuration[FormRowDescriptor.Configuration.Options] = ["hello", "from", "the"]
row4.value = "hello"
self.tableView.reloadData()
}
func cancel(_: UIBarButtonItem!) {
self.performSegueWithIdentifier("goto_main2", sender: self)
}
private func loadForm() {
let form = FormDescriptor(title: "Create Shift Entry")
let section1 = FormSectionDescriptor(headerTitle: nil, footerTitle: nil)
row1.configuration[FormRowDescriptor.Configuration.Options] = str_territory
row1.value = str_territory[0]
section1.addRow(row1)
row2.configuration[FormRowDescriptor.Configuration.Options] = str_company
row2.value = str_company[0]
section1.addRow(row2)
row3.configuration[FormRowDescriptor.Configuration.Options] = str_facility
row3.value = str_facility[0]
section1.addRow(row3)
row4.configuration[FormRowDescriptor.Configuration.Options] = str_specialty
row4.value = str_specialty[0]
section1.addRow(row4)
let section2 = FormSectionDescriptor(headerTitle: nil, footerTitle: nil)
var row = FormRowDescriptor(tag: Static.phoneTag, rowType: .Phone, title: "Scheduled Hours")
row.configuration[FormRowDescriptor.Configuration.CellConfiguration] = ["textField.placeholder" : "e.g. 8", "textField.textAlignment" : NSTextAlignment.Right.rawValue]
section2.addRow(row)
let section3 = FormSectionDescriptor(headerTitle: nil, footerTitle: nil)
row = FormRowDescriptor(tag: Static.birthday, rowType: .DateAndTime, title: "Time In")
section3.addRow(row)
row = FormRowDescriptor(tag: Static.birthday, rowType: .DateAndTime, title: "Time Out")
section3.addRow(row)
let section4 = FormSectionDescriptor(headerTitle: nil, footerTitle: nil)
row = FormRowDescriptor(tag: Static.enabled, rowType: .BooleanSwitch, title: "Missed Lunch")
section4.addRow(row)
let section5 = FormSectionDescriptor(headerTitle: nil, footerTitle: nil)
row = FormRowDescriptor(tag: Static.textView, rowType: .MultilineText, title: "Notes")
section5.addRow(row)
let section8 = FormSectionDescriptor(headerTitle: nil, footerTitle: nil)
row = FormRowDescriptor(tag: Static.button, rowType: .Button, title: "Add Staff Signature")
row.configuration[FormRowDescriptor.Configuration.DidSelectClosure] = {
self.view.endEditing(true)
} as DidSelectClosure
section8.addRow(row)
let section9 = FormSectionDescriptor(headerTitle: nil, footerTitle: nil)
row = FormRowDescriptor(tag: Static.button, rowType: .Button, title: "Add Supervisor Signature")
row.configuration[FormRowDescriptor.Configuration.DidSelectClosure] = {
self.view.endEditing(true)
} as DidSelectClosure
section9.addRow(row)
form.sections = [section1, section2, section3, section4, section5, section8, section9]
self.form = form
form2 = form
}
func load_data(){
let sortDescriptor = NSSortDescriptor(key: "orig_id", ascending: true)
let sortDescriptors = [sortDescriptor]
let facilityPredicate = NSPredicate(format: "facility = %@", NSNumber(integer: 1))
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext
let fetchRequest = NSFetchRequest(entityName:"Company")
fetchRequest.sortDescriptors = sortDescriptors
let fetchRequestTerritory = NSFetchRequest(entityName:"Territory")
fetchRequestTerritory.sortDescriptors = sortDescriptors
let fetchRequestFacility = NSFetchRequest(entityName:"Facility")
fetchRequestFacility.sortDescriptors = sortDescriptors
let fetchRequestSpecialty = NSFetchRequest(entityName:"Specialty")
fetchRequestSpecialty.sortDescriptors = sortDescriptors
fetchRequestSpecialty.predicate = facilityPredicate
let error:NSError
do {
let company_temp = try context.executeFetchRequest(fetchRequest)
company = company_temp as! [Company]
for t in company {
val_company.append(t.orig_id! as Int)
str_company.append(t.name! as String)
}
print(company.count)
let territory_temp = try context.executeFetchRequest(fetchRequestTerritory)
territory = territory_temp as! [Territory]
for t in territory {
val_territory.append(Int(t.orig_id!)!)
str_territory.append(t.name! as String)
}
print(territory_temp.count)
let facility_temp = try context.executeFetchRequest(fetchRequestFacility)
facility = facility_temp as! [Facility]
for t in facility {
val_facility.append(Int(t.orig_id!)!)
str_facility.append(t.name! as String)
}
print(facility_temp.count)
let specialty_temp = try context.executeFetchRequest(fetchRequestSpecialty)
specialty = specialty_temp as! [Specialty]
for t in specialty {
val_specialty.append(Int(t.orig_id!)!)
str_specialty.append(t.name! as String)
}
print(specialty_temp.count)
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
}
func get_facility_ter(company: Int!){
//print("company: " + company)
//print("territory: " + territory!)
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext
let sortDescriptor = NSSortDescriptor(key: "orig_id", ascending: true)
let sortDescriptors = [sortDescriptor]
let fetchRequest = NSFetchRequest(entityName:"Territory")
fetchRequest.sortDescriptors = sortDescriptors
do {
let territory_temp = try context.executeFetchRequest(fetchRequest)
var territory2 = territory_temp as! [Territory]
for t in territory2 {
val_territory.append(Int(t.orig_id!)!)
str_territory.append(t.name! as String)
}
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
if let company2 = company{
let companyPredicate = NSPredicate(format: "company = %@", NSNumber(integer: val_territory[str_territory.indexOf(putu_territory)!]))
let territoryPredicate = NSPredicate(format: "territory = %@", NSNumber(integer: val_territory[company]))
let predicate = NSCompoundPredicate(type: NSCompoundPredicateType.OrPredicateType, subpredicates: [companyPredicate, territoryPredicate])
let fetchRequestFacility = NSFetchRequest(entityName:"Facility")
fetchRequestFacility.predicate = predicate
print(companyPredicate)
do {
let facility_temp = try context.executeFetchRequest(fetchRequestFacility)
facility = facility_temp as! [Facility]
str_facility.removeAll()
val_facility.removeAll()
for t in facility {
val_facility.append(Int(t.orig_id!)!)
str_facility.append(t.name! as String)
}
row3.configuration[FormRowDescriptor.Configuration.Options] = str_facility
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
}
}
func get_facility_com(company: Int!){
//print("company: " + company)
//print("territory: " + territory!)
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext
let sortDescriptor = NSSortDescriptor(key: "orig_id", ascending: true)
let sortDescriptors = [sortDescriptor]
let fetchRequest = NSFetchRequest(entityName:"Company")
fetchRequest.sortDescriptors = sortDescriptors
do {
let company_temp = try context.executeFetchRequest(fetchRequest)
var company2 = company_temp as! [Company]
for t in company2 {
val_company.append(t.orig_id! as Int)
str_company.append(t.name! as String)
}
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
print(val_company.count)
print(str_company.count)
print(putu_company)
print(str_company)
print(str_company.contains(putu_company))
if let company2 = company{
let companyPredicate = NSPredicate(format: "company = %@", NSNumber(integer: val_company[company]))
let territoryPredicate = NSPredicate(format: "territory = %@", NSNumber(integer: val_company[str_company.indexOf(putu_company)!]))
let predicate = NSCompoundPredicate(type: NSCompoundPredicateType.OrPredicateType, subpredicates: [companyPredicate, territoryPredicate])
let fetchRequestFacility = NSFetchRequest(entityName:"Facility")
fetchRequestFacility.predicate = predicate
print(companyPredicate)
do {
let facility_temp = try context.executeFetchRequest(fetchRequestFacility)
facility = facility_temp as! [Facility]
str_facility.removeAll()
val_facility.removeAll()
for t in facility {
val_facility.append(Int(t.orig_id!)!)
str_facility.append(t.name! as String)
}
row3.configuration[FormRowDescriptor.Configuration.Options] = str_facility
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
}
}
func get_specialty(facility_txt: Int!){
print("VALUE OF FACILITY: " + String(facility_txt))
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext
let sortDescriptor = NSSortDescriptor(key: "orig_id", ascending: true)
let sortDescriptors = [sortDescriptor]
let facilityPredicate = NSPredicate(format: "facility = %@", NSNumber(integer: val_facility[str_facility.indexOf(putu_facility)!]))
let fetchRequestSpecialty = NSFetchRequest(entityName:"Specialty")
fetchRequestSpecialty.sortDescriptors = sortDescriptors
fetchRequestSpecialty.predicate = facilityPredicate
do {
let specialty_temp = try context.executeFetchRequest(fetchRequestSpecialty)
specialty = specialty_temp as! [Specialty]
str_specialty.removeAll()
val_specialty.removeAll()
for t in specialty {
val_specialty.append(Int(t.orig_id!)!)
str_specialty.append(t.name! as String)
}
print(str_specialty)
self.form = form2
row4.configuration[FormRowDescriptor.Configuration.Options] = str_specialty
row4.value = "hello"
self.tableView.reloadData()
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
}
func put_company(putu: String!, row: Int!){
print("haler")
putu_company = putu
print(putu_company)
print(row)
get_facility_com(row)
}
func put_territory(putu: String!, row: Int!){
print("haler")
putu_territory = putu
print(putu_territory)
print(row)
get_facility_ter(row)
}
func put_facility(putu: String!, row: Int!){
print("haler")
putu_facility = putu
print(putu_facility)
print(row)
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext
let sortDescriptor = NSSortDescriptor(key: "orig_id", ascending: true)
let sortDescriptors = [sortDescriptor]
let fetchRequestFacility = NSFetchRequest(entityName:"Facility")
fetchRequestFacility.sortDescriptors = sortDescriptors
do {
let facility_temp = try context.executeFetchRequest(fetchRequestFacility)
facility = facility_temp as! [Facility]
for t in facility {
val_facility.append(Int(t.orig_id!)!)
str_facility.append(t.name! as String)
}
} catch let error as NSError {
// failure
print("Fetch failed: \(error.localizedDescription)")
}
print(val_facility)
get_specialty(val_facility[row])
}
}
我在这里调用这些功能:
import UIKit
public class FormPickerCell: FormValueCell, UIPickerViewDelegate, UIPickerViewDataSource {
// MARK: Properties
private let picker = UIPickerView()
private let hiddenTextField = UITextField(frame: CGRectZero)
struct MyVariables {
static var mv_territory = 0
static var mv_company = 0
static var mv_facility = 0
static var mv_specialty = 0
}
// MARK: FormBaseCell
public override func configure() {
super.configure()
accessoryType = .None
picker.delegate = self
picker.dataSource = self
hiddenTextField.inputView = picker
contentView.addSubview(hiddenTextField)
}
public override func update() {
super.update()
titleLabel.text = rowDescriptor.title
if let value = rowDescriptor.value {
valueLabel.text = rowDescriptor.titleForOptionValue(value)
if let options = rowDescriptor.configuration[FormRowDescriptor.Configuration.Options] as? NSArray {
let index = options.indexOfObject(value)
if index != NSNotFound {
picker.selectRow(index, inComponent: 0, animated: false)
}
}
}
}
public override class func formViewController(formViewController: FormViewController, didSelectRow selectedRow: FormBaseCell) {
if selectedRow.rowDescriptor.value == nil {
if let row = selectedRow as? FormPickerCell {
let options = selectedRow.rowDescriptor.configuration[FormRowDescriptor.Configuration.Options] as? NSArray
let optionValue = options?[0] as? NSObject
selectedRow.rowDescriptor.value = optionValue
row.valueLabel.text = selectedRow.rowDescriptor.titleForOptionValue(optionValue!)
row.hiddenTextField.becomeFirstResponder()
}
} else {
if let row = selectedRow as? FormPickerCell {
guard let optionValue = selectedRow.rowDescriptor.value else { return }
row.valueLabel.text = selectedRow.rowDescriptor.titleForOptionValue(optionValue)
row.hiddenTextField.becomeFirstResponder()
}
}
}
// MARK: UIPickerViewDelegate
public func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return rowDescriptor.titleForOptionAtIndex(row)
}
public func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let options = rowDescriptor.configuration[FormRowDescriptor.Configuration.Options] as? NSArray
let optionValue = options?[row] as? NSObject
rowDescriptor.value = optionValue
valueLabel.text = rowDescriptor.titleForOptionValue(optionValue!)
if(rowDescriptor.title == "Company"){
print("company")
print(valueLabel.text)
ExampleFormViewController().put_company(valueLabel.text, row: row)
}else if(rowDescriptor.title == "Territory"){
print("territory")
print(valueLabel.text)
ExampleFormViewController().put_territory(valueLabel.text, row: row)
}
else if(rowDescriptor.title == "Facility"){
print("facility")
print(valueLabel.text)
ExampleFormViewController().put_facility(valueLabel.text, row: row)
}
}
// MARK: UIPickerViewDataSource
public func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
public func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if let options = rowDescriptor.configuration[FormRowDescriptor.Configuration.Options] as? NSArray {
return options.count
}
return 0
}
}
我这样做是为了在其他选择器中的所选项目发生变化时为我的选择器添加新值。
答案 0 :(得分:2)
我认为错误发生在FormPickerCell
方法的pickerView:didSelectRow:inComponent:
中:
ExampleFormViewController().put_territory(valueLabel.text, row: row)
在这一行中,您正在创建ExampleFormViewController
的新实例。我假设你想在你现有的控制器实例上调用这个函数。
最简单(也是最糟糕)的解决方案是使用FormBaseCell. formViewController
属性:
public func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let options = rowDescriptor.configuration[FormRowDescriptor.Configuration.Options] as? NSArray
let optionValue = options?[row] as? NSObject
rowDescriptor.value = optionValue
valueLabel.text = rowDescriptor.titleForOptionValue(optionValue!)
let controller = formViewController as! ExampleFormViewController
if(rowDescriptor.title == "Company"){
controller.put_company(valueLabel.text, row: row)
} else if(rowDescriptor.title == "Territory"){
controller.put_territory(valueLabel.text, row: row)
} else if(rowDescriptor.title == "Facility"){
controller.put_facility(valueLabel.text, row: row)
}
}
但SwiftForm的正确解决方案是使用标准FormPickerCell
(不要仅为一个控制器使用自定义逻辑覆盖它!)并使用row.configuration[FormRowDescriptor.Configuration.DidUpdateClosure]
:
private func loadForm() {
let form = FormDescriptor(title: "Create Shift Entry")
let section1 = FormSectionDescriptor(headerTitle: nil, footerTitle: nil)
row1.configuration[FormRowDescriptor.Configuration.Options] = str_territory
row1.value = str_territory[0]
row1.configuration[FormRowDescriptor.Configuration.DidUpdateClosure] = { [weak self] rowDescriptor in
guard let value = rowDescriptor.value else { return }
guard let options = rowDescriptor.configuration[FormRowDescriptor.Configuration.Options] as? NSArray else { return }
let index = options.indexOfObject(value)
self?.put_territory(rowDescriptor.titleForOptionValue(value), row: index)
}
section1.addRow(row1)
/// add corresponding DidUpdateClosure for row2 and row3
/// ...
}