2017-05-18 4 views
1

les gars Im totalement nouveau dans Rxswift, est-il une façon de faire ce scénario dans RxSwift?RxSwift accès à indexPath.section

Ce que je suis arrivé est ce .. mais le problème est que je n'ai pas indexPath

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) 
      } 

C'est ce que je dois en RxSwift

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 

extrait de source de données:

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 
    )] 
) 

Merci pour toute aide

Répondre

2

Voici un exemple de la mise en pension pour faire une vue de tableau sectionné:

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

Le résultat de c'est que vous devez instancier un RxTableViewSectionedReloadDataSource.

Cependant, je ne vois pas dans votre code où vous avez réellement des sections. Les sections dans un UITableView impliquent un tableau bidimensionnel et vous avez seulement un tableau 1 dimensionnel ...

2

Je suggère d'utiliser RxDataSources. Il vous donnera accès au chemin d'index d'une cellule lorsque vous appelez configureCell.

Votre source et cellules données seront configurées en utilisant quelque chose comme:

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; 
    } 
} 

Vous pouvez laisser les types dans les paramètres de fermeture si vous avez des problèmes pour obtenir les types d'être acceptés. Swift peut les déduire pour vous.


Mise en place struct pour votre source de données personnalisées, y compris vos modèles de section ressemblerait à quelque chose comme ce qui suit:

/// 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 
    } 
} 

L'avant-dernière étape consiste à lier la source de données en plaçant vos sections en un observable. Le code suivant est un exemple dans lequel la fonction sections() retourne un Observable de type Observable<[MySection]>:

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

Enfin, l'obtention des données à apparaître peut être fait en utilisant:

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