2017-10-31 7 views
0

私はSAP Cloud SDK Assistantからアプリケーションを自動生成しました。アプリケーションの詳細ビューでFUIValuePickerFormCellを使用したいと思いますが、そうすることはできません。FUIValuePickerFormCellのピッカービューが表示されない

私はSAP Fioriのメンターアプリケーションから与えられたサンプルコードを使用し、main.storyboardの "FUIValuePickerFormCell"クラスのテーブルビューセルを追加しましたが、セルがタップされてもピッカービューは表示されませんセルも編集可能でもありません。誰もがなぜこれがそうであるか知っていますか?

import SAPFoundation 
import SAPOData 
import SAPFiori 
import SAPCommon 
class DetailViewController: FUIFormTableViewController, Notifier, LoadingIndicator { 

    private let appDelegate = UIApplication.shared.delegate as! AppDelegate 

    private var tableDelegate: DetailTableDelegate! 
    var tableUpdater: TableUpdaterDelegate? 
    var loadingIndicator: FUILoadingIndicatorView? 

    private let logger = Logger.shared(named: "DetailViewControllerLogger") 
    var services: ServicesDataAccess { 
     return appDelegate.services 
    } 

    // The Entity which will be edited on the Detail View 
    var selectedEntity: EntityValue! 
    var entityArray: [EntityValue]! 
    var entityArray2: [EntityValue]! 
    var entityArray3: [EntityValue]! 
    var prodimages: [EntityValue]! 
    var collectionType: CollectionType = .none { 
     didSet { 
      if let delegate = self.generatedTableDelegate() { 
       self.tableDelegate = delegate 
       if self.selectedEntity != nil { 
        self.tableDelegate.entity = self.selectedEntity 
       } 
       if self.entityArray != nil { 
        self.tableDelegate.arrayEntity = self.entityArray 
       } 
       if self.entityArray2 != nil { 
        self.tableDelegate.arrayEntity2 = self.entityArray2 
       } 
       if self.entityArray3 != nil { 
        self.tableDelegate.arrayEntity3 = self.entityArray3 
       } 
       if self.prodimages != nil{ 
        self.tableDelegate.prodimages = self.prodimages 
       } 
      } 
     } 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.tableView.allowsSelection = false 
     self.tableView.dataSource = tableDelegate 
     self.tableView.delegate = tableDelegate 

     self.tableView.rowHeight = UITableViewAutomaticDimension 
     self.tableView.estimatedRowHeight = 44 
    } 

    @IBAction func updateEntity(_ sender: AnyObject) { 
     self.showIndicator() 
     self.view.endEditing(true) 
     self.logger.info("Updating entity in backend.") 
     self.services.service.updateEntity(self.tableDelegate.entity) { error in 
      self.hideIndicator() 

      if let error = error { 
       self.logger.error("Update entry failed.", error: error) 
       self.displayAlert(title: NSLocalizedString("keyErrorEntityUpdateTitle", value: "Update entry failed", comment: "XTIT: Title of alert message about entity update failure."), 
        message: NSLocalizedString("keyErrorEntityUpdateBody", value: error.localizedDescription, comment: "XMSG: Body of alert message about entity update failure.")) 
       return 
      } 

      self.logger.info("Update entry finished successfully.") 
      FUIToastMessage.show(message: NSLocalizedString("keyUpdateEntityFinishedTitle", value: "Updated", comment: "XTIT: Title of alert message about successful entity update.")) 
      self.tableUpdater?.updateTable() 
     } 
    } 

    func createEntity() { 
     self.showIndicator() 
     self.view.endEditing(true) 
     self.logger.info("Creating entity in backend.") 
     self.services.service.createEntity(self.tableDelegate.entity) { error in 
      self.hideIndicator() 

      if let error = error { 
       self.logger.error("Create entry failed.", error: error) 
       self.displayAlert(title: NSLocalizedString("keyErrorEntityCreationTitle", value: "Create entry failed", comment: "XTIT: Title of alert message about entity creation error."), 
        message: NSLocalizedString("keyErrorEntityCreationBody", value: error.localizedDescription, comment: "XMSG: Body of alert message about entity creation error.")) 
       return 
      } 

      self.logger.info("Create entry finished successfully.") 
      DispatchQueue.main.async { 
       self.dismiss(animated: true) { 
        FUIToastMessage.show(message: NSLocalizedString("keyEntityCreationBody", value: "Created", comment: "XMSG: Title of alert message about successful entity creation.")) 
        self.tableUpdater?.updateTable() 
       } 
      } 
     } 
    } 

    func cancel() -> Void { 
     DispatchQueue.main.async { 
      self.dismiss(animated: true, completion: nil) 
     } 
    } 

    // Test code 
    private func updateTable(completionHandler: @escaping() -> Void) { 

     self.tableDelegate?.requestEntities { error in 

      defer { 
       completionHandler() 
      } 

      if let error = error { 
       self.displayAlert(title: NSLocalizedString("keyErrorLoadingData", value: "Loading data failed!", comment: "XTIT: Title of loading data error pop up."), 
        message: error.localizedDescription) 
       self.logger.error("Could not update table.", error: error) 
       return 
      } 

      DispatchQueue.main.async { 
       self.tableView.reloadData() 
       self.logger.info("Table updated successfully!") 
      } 
     } 
    } 

    private func configureView() { 
     if self.collectionType != .none { 
      self.title = collectionType.rawValue 
      if let tableDelegate = self.generatedTableDelegate() { 
       self.tableDelegate = tableDelegate 
       if let tableView = self.tableView { 
        tableView.delegate = tableDelegate 
        tableView.dataSource = tableDelegate 
        self.updateTable() 
       } 
      } 
     } 
    } 

    func updateTable() { 
     self.showIndicator() 
     DispatchQueue.global().async { 
      self.updateTable() { 
       self.hideIndicator() 
      } 
     } 
    } 

    // test code ends 
} 

DetailTableDelegate::以下は私がProductsTypeDetailTableDelegateに

case 6: 
let cell = tableView.dequeueReusableCell(withIdentifier: FUIValuePickerFormCell.reuseIdentifier, for: indexPath) as! FUIValuePickerFormCell 
     valuePickerCell = cell 
     cell.isEditable = true 
     cell.keyName = "Appointment Status" 
     cell.valueOptions = ["1", "2", "3"] 
     cell.value = 1 //index of first value 

     cell.onChangeHandler = { newValue in 
      if let option = self.valuePickerCell?.valueOptions[newValue]{ 
       print("Selected value option \(option)") 
      } 
     } 
     return cell 

DetailViewController変更したい私は

セルを使用するコードは、

import SAPOData 
import SAPFiori 
import SAPFoundation 

protocol DetailTableDelegate: UITableViewDelegate, UITableViewDataSource { 
    var entity: EntityValue { get set } 
    var arrayEntity: [EntityValue] { get set } 
    var arrayEntity2: [EntityValue] { get set } 
    var arrayEntity3: [EntityValue] { get set } 
    var prodimages: [EntityValue] { get set} 
} 

extension DetailTableDelegate { 
} 

extension DetailViewController { 

    func generatedTableDelegate() -> DetailTableDelegate? { 
     switch self.collectionType { 
     case .customers: 
      return CUSTOMERSTypeDetailTableDelegate(dataAccess: self.services, rightBarButton: self.navigationItem.rightBarButtonItem!) 
     case .suppliers: 
      return SUPPLIERSTypeDetailTableDelegate(dataAccess: self.services, rightBarButton: self.navigationItem.rightBarButtonItem!) 
     case .orders: 
      return ORDERSTypeDetailTableDelegate(dataAccess: self.services, rightBarButton: self.navigationItem.rightBarButtonItem!, count: Int()) 
     case .products: 
      return PRODUCTSTypeDetailTableDelegate(dataAccess: self.services, rightBarButton: self.navigationItem.rightBarButtonItem!) 
     default: 
      return nil 
     } 
    } 
} 

ProductsTypeDetailTableDelegate:

import Foundation 
import UIKit 
import SAPOData 
import SAPCommon 
import SAPFiori 

class PRODUCTSTypeDetailTableDelegate: NSObject, DetailTableDelegate { 

    private let dataAccess: ServicesDataAccess 
    private var _entity: PRODUCTSType? 
    // test code 
    private var _arrayEntity: [PRODUCTSType] = [PRODUCTSType]() 
    private var _arrayEntity2: [PRODUCTSType] = [PRODUCTSType]() 
    private var _arrayEntity3: [PRODUCTSType] = [PRODUCTSType]() 
    private var _prodimages: [PRODIMGType] = [PRODIMGType]() 
    var valuePickerCell: FUIValuePickerFormCell? 

    var prodimages: [EntityValue] { 
     get { 
      return _prodimages 
     } 
     set { 
      self._prodimages = newValue as! [PRODIMGType] 
     } 
    } 
    var arrayEntity: [EntityValue] { 
     get { 
      return _arrayEntity 
     } 
     set { 
      self._arrayEntity = newValue as! [PRODUCTSType] 
     } 
    } 
    var arrayEntity2: [EntityValue] { 
     get { 
      return _arrayEntity2 
     } 
     set { 
      self._arrayEntity2 = newValue as! [PRODUCTSType] 
     } 
    } 
    var arrayEntity3: [EntityValue] { 
     get { 
      return _arrayEntity3 
     } 
     set { 
      self._arrayEntity3 = newValue as! [PRODUCTSType] 
     } 
    } 
    // test code ends 
    var entity: EntityValue { 
     get { 
      if _entity == nil { 
       _entity = createEntityWithDefaultValues() 
      } 
      return _entity! 
     } 
     set { 
      _entity = newValue as? PRODUCTSType 
     } 
    } 
    var rightBarButton: UIBarButtonItem 
    private var validity = Array(repeating: true, count: 8) 

    init(dataAccess: ServicesDataAccess, rightBarButton: UIBarButtonItem) { 
     self.dataAccess = dataAccess 
     self.rightBarButton = rightBarButton 
     self.rightBarButton.isEnabled = false 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     guard let currentEntity = self.entity as? PRODUCTSType else { 
      return cellForDefault(tableView: tableView, indexPath: indexPath) 
     } 
     switch indexPath.row { 
     case 0: 
      var value = "" 
      let name = "Product ID" 
      if currentEntity.hasDataValue(for: PRODUCTSType.prodid) { 
       value = "\(currentEntity.prodid)" 
      } 
      return cellForProperty(tableView: tableView, indexPath: indexPath, property: PRODUCTSType.prodid, value: value, name: name, changeHandler: { (newValue: String) -> Bool in 
       if let validValue = TypeValidator.validInteger(from: newValue) { 
        currentEntity.prodid = validValue 
        self.validity[0] = true 
       } else { 
        self.validity[0] = false 
       } 
       self.barButtonShouldBeEnabled() 
       return self.validity[0] 
      }) 
     case 1: 
      var value = "" 
      let name = "Name" 
      if currentEntity.hasDataValue(for: PRODUCTSType.prodname) { 
       if let prodname = currentEntity.prodname { 
        value = "\(prodname)" 
       } 
      } 
      return cellForProperty(tableView: tableView, indexPath: indexPath, property: PRODUCTSType.prodname, value: value, name: name, changeHandler: { (newValue: String) -> Bool in 
       // The property is optional, so nil value can be accepted 
       if newValue.isEmpty { 
        currentEntity.prodname = nil 
        self.validity[1] = false 
       } else { 
        if let validValue = TypeValidator.validString(from: newValue, for: PRODUCTSType.prodname) { 
         currentEntity.prodname = validValue 
         self.validity[1] = true 
        } else { 
         self.validity[1] = false 
        } 
       } 
       self.barButtonShouldBeEnabled() 
       return self.validity[1] 
      }) 
     case 2: 
      var value = "" 
      let name = "Description" 
      if currentEntity.hasDataValue(for: PRODUCTSType.proddesc) { 
       if let proddesc = currentEntity.proddesc { 
        value = "\(proddesc)" 
       } 
      } 
      return cellForProperty(tableView: tableView, indexPath: indexPath, property: PRODUCTSType.proddesc, value: value, name: name, changeHandler: { (newValue: String) -> Bool in 
       // The property is optional, so nil value can be accepted 
       if newValue.isEmpty { 
        currentEntity.proddesc = nil 
        self.validity[2] = false 
       } else { 
        if let validValue = TypeValidator.validString(from: newValue, for: PRODUCTSType.proddesc) { 
         currentEntity.proddesc = validValue 
         self.validity[2] = true 
        } else { 
         self.validity[2] = false 
        } 
       } 
       self.barButtonShouldBeEnabled() 
       return self.validity[2] 
      }) 
     case 3: 
      var value = "" 
      let name = "Current Stock" 
      if currentEntity.hasDataValue(for: PRODUCTSType.currstock) { 
       if let currstock = currentEntity.currstock { 
        value = "\(currstock)" 
       } 
      } 
      return cellForProperty(tableView: tableView, indexPath: indexPath, property: PRODUCTSType.currstock, value: value, name: name, changeHandler: { (newValue: String) -> Bool in 
       // The property is optional, so nil value can be accepted 
       if newValue.isEmpty { 
        currentEntity.currstock = 0 
        self.validity[3] = true 
       } else { 
        if let validValue = TypeValidator.validInteger(from: newValue) { 
         currentEntity.currstock = validValue 
         self.validity[3] = true 
        } else { 
         self.validity[3] = false 
        } 
       } 
       self.barButtonShouldBeEnabled() 
       return self.validity[3] 
      }) 
     case 4: 
      var value = "" 
      let name = "Minimum Stock" 
      if currentEntity.hasDataValue(for: PRODUCTSType.minstock) { 
       if let minstock = currentEntity.minstock { 
        value = "\(minstock)" 
       } 
      } 
      return cellForProperty(tableView: tableView, indexPath: indexPath, property: PRODUCTSType.minstock, value: value, name: name, changeHandler: { (newValue: String) -> Bool in 
       // The property is optional, so nil value can be accepted 
       if newValue.isEmpty { 
        currentEntity.minstock = 0 
        self.validity[4] = true 
       } else { 
        if let validValue = TypeValidator.validInteger(from: newValue) { 
         currentEntity.minstock = validValue 
         self.validity[4] = true 
        } else { 
         self.validity[4] = false 
        } 
       } 
       self.barButtonShouldBeEnabled() 
       return self.validity[4] 
      }) 
     case 5: 
      var value = "" 
      let name = "Price" 
      if currentEntity.hasDataValue(for: PRODUCTSType.price) { 
       if let price = currentEntity.price { 
        value = "\(price)" 
       } 
      } 
      return cellForProperty(tableView: tableView, indexPath: indexPath, property: PRODUCTSType.price, value: value, name: name, changeHandler: { (newValue: String) -> Bool in 
       // The property is optional, so nil value can be accepted 
       if newValue.isEmpty { 
        currentEntity.price = nil 
        self.validity[5] = false 
       } else { 
        if let validValue = TypeValidator.validBigDecimal(from: newValue) { 
         currentEntity.price = validValue 
         self.validity[5] = true 
        } else { 
         self.validity[5] = false 
        } 
       } 
       self.barButtonShouldBeEnabled() 
       return self.validity[5] 
      }) 
     case 6: 
//   var value = "" 
//   let name = "Category" 
//   if currentEntity.hasDataValue(for: PRODUCTSType.cat) { 
//    if let cat = currentEntity.cat { 
//     value = "\(cat)" 
//    } 
//   } 
//   return cellForProperty(tableView: tableView, indexPath: indexPath, property: PRODUCTSType.cat, value: value, name: name, changeHandler: { (newValue: String) -> Bool in 
//    // The property is optional, so nil value can be accepted 
//    if newValue.isEmpty { 
//     currentEntity.cat = nil 
//     self.validity[6] = false 
//    } else { 
//     if let validValue = TypeValidator.validString(from: newValue, for: PRODUCTSType.cat) { 
//      currentEntity.cat = validValue 
//      self.validity[6] = true 
//     } else { 
//      self.validity[6] = false 
//     } 
//    } 
//    self.barButtonShouldBeEnabled() 
//    return self.validity[6] 
//   }) 
      let cell = tableView.dequeueReusableCell(withIdentifier: FUIValuePickerFormCell.reuseIdentifier, for: indexPath) as! FUIValuePickerFormCell 
      valuePickerCell = cell 
      cell.isEditable = true 
      cell.keyName = "Appointment Status" 
      cell.valueOptions = ["1", "2", "3"] 
      cell.value = 1 //index of first value 

      cell.onChangeHandler = { newValue in 
       if let option = self.valuePickerCell?.valueOptions[newValue]{ 
        print("Selected value option \(option)") 
       } 
      } 
      return cell 

     case 7: 
      var value = "" 
      let name = "Supplier ID" 
      if currentEntity.hasDataValue(for: PRODUCTSType.suppid) { 
       if let suppid = currentEntity.suppid { 
        value = "\(suppid)" 
       } 
      } 
      return cellForProperty(tableView: tableView, indexPath: indexPath, property: PRODUCTSType.suppid, value: value, name: name, changeHandler: { (newValue: String) -> Bool in 
       // The property is optional, so nil value can be accepted 
       if newValue.isEmpty { 
        currentEntity.suppid = nil 
        self.validity[7] = true 
       } else { 
        if let validValue = TypeValidator.validInteger(from: newValue) { 
         currentEntity.suppid = validValue 
         self.validity[7] = true 
        } else { 
         self.validity[7] = false 
        } 
       } 
       self.barButtonShouldBeEnabled() 
       return self.validity[7] 
      }) 
     default: 
      return cellForDefault(tableView: tableView, indexPath: indexPath) 
     } 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return 8 
    } 

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 
     return true 
    } 

    func createEntityWithDefaultValues() -> PRODUCTSType { 
     let newEntity = PRODUCTSType() 
     newEntity.prodid = self._arrayEntity.count + 1 
     return newEntity 
    } 

    // Check if all text fields are valid 
    private func barButtonShouldBeEnabled() { 
     let anyFieldInvalid = self.validity.first { (field) -> Bool in 
      return field == false 
     } 
     self.rightBarButton.isEnabled = anyFieldInvalid == nil 
    } 

    func cellForProperty(tableView: UITableView, indexPath: IndexPath, property: Property, value: String, name: String, changeHandler: @escaping((String) -> Bool)) -> UITableViewCell { 
     let cell: UITableViewCell! 

     if property.dataType.isBasic { 
      // The property is a key or we are creating new entity 
      if (!property.isKey || self.entity.isNew) { 
       // .. that CAN be edited 
       cell = self.cellWithEditableContent(tableView: tableView, indexPath: indexPath, property: property, with: value, with: name, changeHandler: changeHandler) 
      } else { 
       // .. that CANNOT be edited 
       cell = self.cellWithNonEditableContent(tableView: tableView, indexPath: indexPath, for: property.name, with: value, with: name) 
      } 
     } else { 
      // A complex property 
      cell = self.cellWithNonEditableContent(tableView: tableView, indexPath: indexPath, for: property.name, with: "...", with: name) 
     } 
     return cell 
    } 

    func cellForDefault(tableView: UITableView, indexPath: IndexPath) -> FUISimplePropertyFormCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: FUISimplePropertyFormCell.reuseIdentifier, for: indexPath) as! FUISimplePropertyFormCell 
     cell.textLabel!.text = "" 
     cell.textLabel!.numberOfLines = 0 
     cell.textLabel!.lineBreakMode = NSLineBreakMode.byWordWrapping 
     cell.keyName = "default" 

     return cell 
    } 

    private func cellWithEditableContent(tableView: UITableView, indexPath: IndexPath, property: Property, with value: String, with name: String, changeHandler: @escaping((String) -> Bool)) -> FUISimplePropertyFormCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: FUISimplePropertyFormCell.reuseIdentifier, for: indexPath) as! FUISimplePropertyFormCell 

     cell.isEditable = true 
     cell.keyName = name 
     cell.value = value 

     if !property.isOptional { 
      cell.valueTextField!.placeholder = NSLocalizedString("keyRequiredPlaceholder", value: "Required", comment: "XSEL: Placeholder text for required but currently empty textfield.") 
     } 

     cell.onChangeHandler = { (newValue) -> Void in 
      if !changeHandler(newValue) { 
       cell.valueTextField.textColor = UIColor.red 
      } else { 
       cell.valueTextField.textColor = UIColor.gray 
      } 
     } 

     return cell 
    } 

    private func cellWithNonEditableContent(tableView: UITableView, indexPath: IndexPath, for key: String, with value: String, with name: String) -> FUISimplePropertyFormCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: FUISimplePropertyFormCell.reuseIdentifier, for: indexPath) as! FUISimplePropertyFormCell 

     cell.keyName = name 
     cell.value = value 

     return cell 
    } 

    private func selectKeyboardFor(_ type: DataType) -> UIKeyboardType { 
     switch type.code { 
     case DataType.byte, DataType.short, DataType.integer, DataType.int: 
      return .decimalPad 
     case DataType.decimal, DataType.double, DataType.localDateTime, DataType.globalDateTime: 
      return .numbersAndPunctuation 
     default: 
      return .`default` 
     } 
    } 

    func defaultValueFor(_ property: Property) -> Double { 
     if let defaultValue = property.defaultValue { 
      return Double(defaultValue.toString())! 
     } else { 
      return Double() 
     } 
    } 

    func defaultValueFor(_ property: Property) -> BigDecimal { 
     if let defaultValue = property.defaultValue { 
      return (defaultValue as! DecimalValue).value 
     } else { 
      return BigDecimal.fromDouble(Double()) 
     } 
    } 

    func defaultValueFor(_ property: Property) -> Int { 
     if let defaultValue = property.defaultValue { 
      return Int(defaultValue.toString())! 
     } else { 
      return Int() 
     } 
    } 

    func defaultValueFor(_ property: Property) -> BigInteger { 
     if let defaultValue = property.defaultValue { 
      return BigInteger(defaultValue.toString()) 
     } else { 
      return BigInteger.fromInt(Int()) 
     } 
    } 

    func defaultValueFor(_ property: Property) -> Int64 { 
     if let defaultValue = property.defaultValue { 
      return Int64(defaultValue.toString())! 
     } else { 
      return Int64() 
     } 
    } 

    func defaultValueFor(_ property: Property) -> Float { 
     if let defaultValue = property.defaultValue { 
      return Float(defaultValue.toString())! 
     } else { 
      return Float() 
     } 
    } 

    func defaultValueFor(_ property: Property) -> LocalDateTime { 
     if let defaultValue = property.defaultValue { 
      return LocalDateTime.parse(defaultValue.toString())! 
     } else { 
      return LocalDateTime.now() 
     } 
    } 

    func defaultValueFor(_ property: Property) -> GlobalDateTime { 
     if let defaultValue = property.defaultValue { 
      return GlobalDateTime.parse(defaultValue.toString())! 
     } else { 
      return GlobalDateTime.now() 
     } 
    } 

    func defaultValueFor(_ property: Property) -> GuidValue { 
     if let defaultValue = property.defaultValue { 
      return GuidValue.parse(defaultValue.toString())! 
     } else { 
      return GuidValue.random() 
     } 
    } 

    func defaultValueFor(_ property: Property) -> String { 
     if let defaultValue = property.defaultValue { 
      return defaultValue.toString() 
     } else { 
      return "" 
     } 
    } 

    func defaultValueFor(_ property: Property) -> Bool { 
     if let defaultValue = property.defaultValue { 
      return defaultValue.toString().toBool()! 
     } else { 
      return Bool() 
     } 
    } 
} 

答えて

0

あなたの説明から、私はあなたがFUIFormTableViewControllerではなくUITableViewControllerを使用していると仮定します。 "FUI * FormCells"のイベントは、UITableViewControllerではなく、FUIFormTableViewControllerによってのみ処理されます。

+0

私はFUIFormTableViewControllerに変更しようとしましたが、何も変わらない、リストピッカーはまだ出てこない。 – Anthony

+0

ディテール・ビュー・コントローラ・クラスを共有してもらえますか、またはあなたのプロジェクトはgithubで利用できますか? –

+0

私は質問を編集し、必要なコードを挿入しました。基本的には、iOSアシスタント用のSAP Cloud Platform SDKによって生成されたマスター詳細アプリケーションのコピー – Anthony

関連する問題