【问题标题】:How to make Dynamic sections with RxDataSource?如何使用 RxDataSource 制作动态部分?
【发布时间】:2021-05-27 18:30:13
【问题描述】:

我要实现的目标的概述我正在尝试制作一个通知表格视图,每个通知都按其创建日期分组,因此表格视图部分将是创建日期的数量,每个部分都包含在此创建的通知节标题中的日期。 我已经搜索了很多,但没有得到一个绝对的答案如何使用 RxDataSource 数组是动态加载的,通过 API 接收到的日期?

class T : UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return array.count
    }
}

我所发现的只是将这些部分设置为静态

       ViewModel.AllNotificationsObservable
                .map({ [NotificationSectionViewModel(header: "Yet", items: $0.filter{$0.createAt.toDate()!.toString(format: "yyyy-MM-dd") == Date().toString(format: "yyyy-MM-dd") }),
                        NotificationSectionViewModel(header: "Yesterday", items: $0)
                ]
                })
                .bind(to: NotificationTableView.rx.items(dataSource: ViewModel.dataSource))
                .disposed(by: notificationDisposeBag)

这是我的结构

struct NotificationSectionViewModel {
    var header: String
    var items: [AllNotificationModel] 
}
extension NotificationSectionViewModel: SectionModelType {
    typealias NotificationItem = AllNotificationModel
    
    init(original: NotificationSectionViewModel, items: [AllNotificationModel]) {
        self = original
        self.items = items
    }
}

这是数据模型

class AllNotificationModel : Codable {
    
    let id, userID : Int
    let title, body, createAt: String
    
    enum CodingKeys: String, CodingKey {
        case id, title, body
        case userID = "user_id"
        case createAt = "create at"
    }
}

我想要达到的目标

需要这样的标题

“Today”: [
        {
            "id": 2421,
            "user_id": 39,
            "title": "todayNotification",
            "body": "test",
            "create at": "2021-02-26 17:33:44"
        },
        {
            "id": 2349,
            "user_id": 39,
            "title": "check",
            "body": "test",
            "create at": "2021-02-26 09:36:05"
        },
        {
            "id": 2206,
            "user_id": 39,
            "title": "New Deal",
            "body": "new Deal 2",
            "create at": "2021-02-26 13:43:16"
        } ]
“Yesterday”: [
        {
            "id": 2134,
            "user_id": 39,
            "title": "Closed Deal",
            "body": “deal deal”,
            "create at": "2021-02-25 13:21:30"
        } ]

“2021-02-24”: [
        {
            "id": 2134,
            "user_id": 39,
            "title": "Closed Deal",
            "body": “deal”,
            "create at": "2021-02-24 13:21:30"
        },
        {
            "id": 2063,
            "user_id": 39,
            "title": "New Deal",
            "body": "new Deal",
            "create at": "2021-02-24 13:21:16"
        }]

【问题讨论】:

    标签: ios swift rx-swift rxdatasources


    【解决方案1】:

    在 RxDataSources 的 example 中,我们有:

    Observable.just(sections)
      .bind(to: tableView.rx.items(dataSource: dataSource))
      .disposed(by: disposeBag)
    

    您需要做的就是将 Observable.just(sections) 替换为绑定到您的数据的 Observable。假设notificationsObservable<[Notifications]>。然后你做这样的事情:

    notifications.map { sections(from: $0) }
      .bind(to: tableView.rx.items(dataSource: dataSource))
      .disposed(by: disposeBag)
    

    sections(from: $0)[Notification] 数组到sections 数组的转换,在某处定义它。您的部分结构必须符合协议SectionModelType

    struct SectionOfNotification {
      var header: String    
      var items: [Item]
    }
    
    extension SectionOfNotification : SectionModelType {
      typealias Item = Notification
    
       init(original: SectionOfNotification, items: [Item]) {
        self = original
        self.items = items
      }
    }
    

    我的例子:

    public lazy var appSections: Driver<[AppSection]> = {
        Driver.combineLatest(chatAppCollectionData, functionAppCollectionData) { ($0, $1) }
            .map { (chatAppCollectionData, functionAppCollectionData) -> [AppSection] in
                let appSection1 = AppSection(header: NSLocalizedString("DASHBOARD_RECENT_CHATS", comment: ""),
                                             items: chatAppCollectionData)
    
                let appSection2 = AppSection(header: NSLocalizedString("DASHBOARD_OTHERS", comment: ""),
                                             items: functionAppCollectionData)
    
                return [
                    appSection1,
                    appSection2
                ]
            }
    }()
    

    这是部分:

    import RxDataSources
    
    struct AppSection {
        var header: String
        var items: [Item]
    }
    
    extension AppSection: SectionModelType {
        typealias Item = EONApp
    
        init(original: AppSection, items: [Item]) {
            self = original
            self.items = items
        }
    }
    

    【讨论】:

    • 我不知道如何从 [AllNotificationModel] 中获取部分,这是我的结构。 ` struct NotificationSectionViewModel { var header: String var items: [AllNotificationModel] } extension NotificationSectionViewModel: SectionModelType { typealias NotificationItem = AllNotificationModel init(original: NotificationSectionViewModel, items: [AllNotificationModel]) { self = original self.items = items } } ` @Denis
    • @Adam,添加了一个真实项目的示例。您只需要从模型对象初始化 SectionModelType 对象。
    • 你刚刚放了两个部分的数据,我要问的是一个动态部分取决于通知的日期,假设所有通知在 26-02-2021,然后所有通知在 20- 02-2021 等等,不仅仅是今天和昨天,如果我有今天的通知,我会把它们都放在今天调用的部分下
    • 我在图片后添加了我的意思,请检查@Denis
    【解决方案2】:

    我想出了答案

    override func bind(ViewModel: NotificationViewModel) {
    
            
            ViewModel.dataSource.configureCell = { [unowned self] (dataSource, tableview, indexPath, item)  in
                let cell = tableview.dequeueReusableCell(withIdentifier: self.CellIdentifier, for: indexPath) as! NotificationTableViewCell
                cell.setDataToUI(notificationData: item)
                return cell
            }
    
            ViewModel.dataSource.titleForHeaderInSection = { (dataSource, index) in
                let section = dataSource[index]
                return section.header
            }
        
            var finalSections = [NotificationSectionViewModel]()
            var sortedFinal = [NotificationSectionViewModel]()
            var result = [String : [AllNotificationModel]]()
                ViewModel.AllNotificationsObservable
                    .map({ section in
          for (i, dict) in section.enumerated() {
                            result[(section[i].createAt.toDate()?.toString(format: "yyyy-MM-dd"))!, default: []].append(dict)
                        }
                        
                        for (key, value) in result {
                            finalSections.append(NotificationSectionViewModel(header: key, items: value))
                        }
                        
                        sortedFinal = finalSections.sorted(by: >)
                        
                        for final in 0...sortedFinal.count - 1 {
                            if self.getTodayDate() == sortedFinal[final].header {
                                sortedFinal[final].header = "Today"
                            }
                            else if self.getYesterDay() == sortedFinal[final].header {
                                sortedFinal[final].header = "Yesterday"
                            }
                            else {
                                    sortedFinal[final].header = convertDateFormater(sortedFinal[final].header)
                                
                            }
                        }
                        
                        return sortedFinal
                    })
                    .bind(to: NotificationTableView.rx.items(dataSource: ViewModel.dataSource))
                    .disposed(by: notificationDisposeBag)
    }
    

    这是我的单元格

    class NotificationTableViewCell: UITableViewCell {
    
        @IBOutlet weak var notificationImageIcon: UIImageView!
        @IBOutlet weak var notificationBodyMessage: UILabel!
        @IBOutlet weak var notificationTime: UILabel!
        @IBOutlet weak var seenNotificationView: UIView!
        
    
        override func awakeFromNib() {
              super.awakeFromNib()
              // Initialization code
              selectionStyle = .none
          }
    
        func setDataToUI(notificationData: AllNotificationModel) {
            DispatchQueue.main.async {
                self.seenNotificationView.isHidden = true
                self.notificationBodyMessage.text = notificationData.body
                self.notificationTime.text = self.convertDateFormater(notificationData.createAt)
            }
        }
        
        func convertDateFormater(_ date: String) -> String
            {
                let dateFormatter = DateFormatter()
                dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
                let date = dateFormatter.date(from: date)
                dateFormatter.dateFormat = "h:mm a"
                return  dateFormatter.string(from: date!)
    
            }
    
    }
    

    我使用这两个函数来获取今天和昨天的日期

    extension UIViewController {
        func getTodayDate() -> String {
            let currentDate = Date()
            let df = DateFormatter()
            df.dateFormat = "yyyy-MM-dd"
            let dateString = df.string(from: currentDate)
            return dateString
        }
    
        func getYesterDay() -> String {
            let currentDate = Date.yesterday
            let df = DateFormatter()
            df.dateFormat = "yyyy-MM-dd"
            let dateString = df.string(from: currentDate)
            return dateString
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多