2016-03-21 52 views
0

我正在使用Swift窗體庫:https://github.com/ortuman/SwiftForms這與Eureka非常相似。聲明失敗:self.form屬性務必分配

這裏是什麼,我試圖做一個解釋:在我的形式

我有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 
    } 

我試圖做到的是這樣的: enter image description here

我有幾個拾荒者,最後選擇器將取決於從第二選擇的項目和第三。我稱這些功能爲更新我最後一個選擇器的內容。

這裏是我的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

你是什麼意思? –

+0

現在是相同的@matt –

+0

如果你想要人們回答,你將不得不簡化代碼到最小的例子。有太多的代碼對這個問題沒有任何重要性,並且我覺得某些重要的部分不見了。 – Sulthan

回答

2

我相信錯誤是在FormPickerCellpickerView:didSelectRow:inComponent:方法:

ExampleFormViewController().put_territory(valueLabel.text, row: row) 

在這一行,你要創建的ExampleFormViewController一個實例。我假設你想在你現有的控制器實例上調用這個函數。

最簡單的(和wrongest)解決方案是使用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 
    /// ... 
} 
+0

謝謝!將嘗試實現這個現在 –

+0

Awww。我的xcode正在更新。 DidUpdateClosure做什麼?它在什麼後被解僱? –

+0

在row.value更改後調用:https://github.com/ortuman/SwiftForms/blob/master/SwiftForms/descriptors/FormRowDescriptor.swift#L96 – glyuck