2016-11-06 8 views
3

RxSwiftを使用して複数のセクションでテーブルビューを作成しようとしています。各セクションには、異なるタイプを表すデータが表示されます。RxSwiftとRxSwiftDataSourcesを使用して異なるデータタイプを表す複数のセクションでテーブルビューをバインドするにはどうすればよいですか?

私はRxSwiftDataSourcesライブラリを見つけ、そのドキュメントからその例を実装しました。ここ

その例が実装されている方法の迅速runthroughある:カスタムデータ型CustomDataが定義されている

struct CustomData { 
    var anInt: Int 
    var aString: String 
    var aCGPoint: CGPoint 
} 

そして、セクションの表現が(添加さSectionModelTypeが実装されていることに注意してくださいここで):

struct SectionOfCustomData { 
    var header: String  
    var items: [Item] 
} 
extension SectionOfCustomData: SectionModelType { 
    typealias Item = CustomData 

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

最後に、いくつかのサンプルデータが作成され、テーブルビューにバインドされます。

let sections: [SectionOfCustomData] = [ 
    SectionOfCustomData(header: "First section", items: [CustomData(anInt: 0, aString: "zero", aCGPoint: CGPoint.zero), CustomData(anInt: 1, aString: "one", aCGPoint: CGPoint(x: 1, y: 1)) ]), 
    SectionOfCustomData(header: "Second section", items: [CustomData(anInt: 2, aString: "two", aCGPoint: CGPoint(x: 2, y: 2)), CustomData(anInt: 3, aString: "three", aCGPoint: CGPoint(x: 3, y: 3)) ]) 
] 

は、私は今の例を変更したいとだけ第二項にCustomDataStringのではなく、インスタンスを表示したいので、多少のように:

let sections = [ 
    SectionOfCustomData(header: "First section", items: [CustomData(anInt: 0, aString: "zero", aCGPoint: CGPoint.zero), CustomData(anInt: 1, aString: "one", aCGPoint: CGPoint(x: 1, y: 1)) ]), 
    SectionOfString(header: "Second section", items: ["a", "b", "c"]) 
] 

これは明らかにsectionsとしてコンパイルされませんさまざまな種類の要素が含まれていますSectionOfCustomDataSectionOfString。コンパイラはと文句を言う、私は[SectionModelType]としてセクションを宣言しようとすることでこの問題を回避しようとしたが、これは動作しません:

それは自己または関連タイプの要件を持っているので、議定書SectionModelType 'の唯一の一般的な制約として使用することができます

+0

あなたは既に解決策を持っていましたか? –

答えて

2

さまざまな種類のラップにenumを使用できます。列挙型を使用して

、SectionOfCustomDataの定義は次のようにする必要があります:

enum SectionOfCustomData: SectionModelType { 

    typealias Item = Row 

    case customDataSection(header: String, items: [Row]) 
    case stringSection(header: String, items: [Row]) 

    enum Row { 
    case customData(customData: CustomData) // wrapping CustomData to Row type 
    case string(string: String)    // wrapping String to Row type 
    } 

    // followings are not directly related to this topic, but represents how to conform to SectionModelType 
    var items: [Row] { 
    switch self { 
    case .customDataSection(_, let items): 
     return items 

    case .stringSection(_, let items): 
     return items 
    } 
    } 

    public init(original: SectionOfCustomData, items: [Row]) { 
    switch self { 
    case .customDataSection(let header, _): 
     self = .customDataSection(header: header, items: items) 

    case .stringSection(let header, _): 
     self = .stringSection(header: header, items: items) 
    } 
    } 
} 

そしてconfigureCellは、次のようになります

let dataSource = RxTableViewSectionedReloadDataSource<SectionOfCustomData>() 
... 
dataSource.configureCell = { [weak self] (dataSource, tableView, indexPath, row) -> UITableViewCell in 

    switch dataSource[indexPath] { 
    case .customData(let customData): 
    let cell: CustomDataCell = // dequeue cell 
    self?.configure(cell: cell, with: customData) 
    return cell 

    case .string(let string): 
    let cell: StringCell = // dequeue cell 
    self?.configure(cell: cell, with: string) 
    return cell 
    } 
} 
+0

'init'の' switch self'ではなく 'switch original'でしょうか? – d4Rk

関連する問題