2017-05-18 15 views
1

Jungs Ich bin völlig neu in Rxswift, gibt es eine Möglichkeit, dieses Szenario in RxSwift zu tun?RxSwift Zugriff auf indexPath.section

Was habe ich das ist .. aber Problem ist, ich habe indexPath nicht

datasource.sectionModels 
     .asObservable() 
     .bindTo(tableView.rx.items) { tableView, row, element in 
      guard let sectionType = SectionType(rawValue: indexPath.section) else { return 0 } 

      let indexPath = IndexPath(row: row, section: 0) 

      var itemForIndexPath: SectionViewModel { 
       return self.datasource.sectionModels.value[indexPath.section] 
      } 

      switch sectionType { 
      case .nickTitle, .nickIfno: 
       let infoCell = tableView.dequeueReusableCell(
        withIdentifier: InfoTableViewCell.name, 
        for: indexPath 
        ) as! InfoTableViewCell 

       var datasource: InfoCellDatasourceProtocol = InfoCellNormalState(text: itemForIndexPath.text) 
       if itemForIndexPath.errorStyle { 
        datasource = InfoCellErrorState(text: itemForIndexPath.text) 
       } 

       infoCell.configureCell(datasource: datasource) 
      } 

Dies ist, was ich in RxSwift brauchen

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    guard let sectionType = SectionType(rawValue: indexPath.section) else { return UITableViewCell() } 

    var itemForIndexPath: SectionViewModel { 
     return self.datasource.sectionModels.value[indexPath.section] 
    } 

    switch sectionType { 
    case .nickTitle, .nickInfo: 
     let infoCell = tableView.dequeueReusableCell(
      withIdentifier: InfoTableViewCell.name, 
      for: indexPath 
      ) as! InfoTableViewCell 

     var datasource: InfoCellDatasourceProtocol = InfoCellNormalState(text: itemForIndexPath.text) 
     if itemForIndexPath.errorStyle { 
      datasource = InfoCellErrorState(text: itemForIndexPath.text) 
     } 

     infoCell.configureCell(datasource: datasource) 

     return infoCell 

Datenquelle Schnipsel:

open class RegistrationNickDataSource: NickDatasourceProtocol { 
    public var error: Variable<ErrorType>? 
    public var success: Variable<Bool> = Variable(false) 
    fileprivate let request = ValidateNameRequest() 


    public var nickHints: Variable<[String]>? 
    public var sectionModels: Variable<[SectionViewModel]> = Variable([ 
    SectionViewModel(
     text: "your_nick_hint".localized, 
     type: .info, 
     errorStyle: false 
    ), 
    SectionViewModel(
     text: "your_nick_placeholder".localized, 
     type: .input, 
     errorStyle: false 
    ), 
    SectionViewModel(
     text: "your_nick_info".localized, 
     type: .info, 
     errorStyle: false 
    )] 
) 

Dank für jede Hilfe

Antwort

2

Hier ist ein Beispiel aus dem Repo eine geschnittene Tabellenansicht zu machen:

https://github.com/ReactiveX/RxSwift/blob/master/RxExample/RxExample/Examples/SimpleTableViewExampleSectioned/SimpleTableViewExampleSectionedViewController.swift

Das Ergebnis davon ist, dass Sie ein RxTableViewSectionedReloadDataSource zu instanziiert haben.

Allerdings sehe ich nicht in Ihrem Code, wo Sie tatsächlich Abschnitte haben. Abschnitte in einem UITableView implizieren ein zweidimensionales Array und Sie haben nur ein 1-dimensionales Array ...

2

Ich empfehle die Verwendung RxDataSources. Sie erhalten Zugriff auf den Indexpfad einer Zelle, wenn Sie configureCell anrufen.

Ihre Datenquelle und Zelle mit so etwas wie konfiguriert werden:

func setupDataSource() 
{ 
    let dataSource = RxTableViewSectionedReloadDataSource<MySection>() 

    dataSource.configureCell = { (theDataSource: TableViewSectionedDataSource<MySection>,      
            theTableView,   
               theIndexPath,         
               item: MyItem) in 
     let cell = theTableView.dequeueReusableCell(withIdentifier: InfoTableViewCell.name, 
                for: theIndexPath) as! InfoTableViewCell 

     /* Do any setup of the cell here. */ 

     return cell; 
    }  

    dataSource.titleForHeaderInSection = { theDataSource, index in 
     return theDataSource.sectionModels[index].header; 
    } 
} 

Sie können die Typen in den Verschluss Parameter auslassen, wenn Sie Probleme haben die Typen immer akzeptiert werden. Swift kann sie für Sie ableiten.


Einrichten structs für Ihre Quelle benutzerdefinierte Daten Ihrer Abschnitt Modelle einschließlich etwa wie folgt aussehen:

/// Holds data to display. 
struct MyItem 
{ 
    var text: String 
    var type: MyCustomEnum 
    var errorStyle: Bool 
} 

/// Defines a section type for use with sections for the table. 
struct MySection 
{ 
    var header: String 
    var items: [Item] 
} 

/// Tie your custom data model to SectionModelType. 
extension MySection: SectionModelType 
{ 
    typealias Item = MyItem 

    init(original: MySection, 
     items: [Item]) 
    { 
     self = original 
     self.items = items 
    } 
} 

Der vorletzte Schritt ist die Datenquelle zu binden, indem Sie Ihre Abschnitte Platzierung in ein Observabler. Der folgende Code ist ein Beispiel, bei dem die Funktion sections() einen beobachtbaren vom Typ gibt Observable<[MySection]>:

sections() 
    .bind(to: tableView.rx.items(dataSource: dataSource)) 
    .disposed(by: bag) 

schließlich die Daten bekommen kann erscheinen tun mit:

override func viewDidLoad() 
{ 
    super.viewDidLoad() 
    setupDataSource() 
}