如何使用 RxDataSource 制作动态部分?
How to make Dynamic sections with RxDataSource?
我正在尝试实现的目标的概述我正在尝试创建一个通知表视图,每个通知都按其创建日期分组,因此表视图部分将是创建日期的数量,每个部分都有创建的通知在该节标题中的这个日期。
我搜索了很多但没有得到如何使用 RxDataSource 制作的绝对答案
该数组是动态加载的,其中包含通过 API?
接收到的日期
class T : UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return array.count
}
}
我发现的所有内容都是像这样将部分设置为静态的
ViewModel.AllNotificationsObservable
.map({ [NotificationSectionViewModel(header: "Yet", items: [=11=].filter{[=11=].createAt.toDate()!.toString(format: "yyyy-MM-dd") == Date().toString(format: "yyyy-MM-dd") }),
NotificationSectionViewModel(header: "Yesterday", items: [=11=])
]
})
.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"
}
}
我想要达到的目标
需要header这样
“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"
}]
在 RxDataSources 的 example 中,我们有:
Observable.just(sections)
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
您需要做的就是将 Observable.just(sections) 替换为绑定到您的数据的 Observable。假设 notifications
是一个 Observable<[Notifications]>
。然后你做这样的事情:
notifications.map { sections(from: [=11=]) }
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
sections(from: [=17=])
是[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) { ([=13=], ) }
.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
}
}
我找到答案了
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
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
}
}
我正在尝试实现的目标的概述我正在尝试创建一个通知表视图,每个通知都按其创建日期分组,因此表视图部分将是创建日期的数量,每个部分都有创建的通知在该节标题中的这个日期。 我搜索了很多但没有得到如何使用 RxDataSource 制作的绝对答案 该数组是动态加载的,其中包含通过 API?
接收到的日期class T : UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return array.count
}
}
我发现的所有内容都是像这样将部分设置为静态的
ViewModel.AllNotificationsObservable
.map({ [NotificationSectionViewModel(header: "Yet", items: [=11=].filter{[=11=].createAt.toDate()!.toString(format: "yyyy-MM-dd") == Date().toString(format: "yyyy-MM-dd") }),
NotificationSectionViewModel(header: "Yesterday", items: [=11=])
]
})
.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"
}
}
我想要达到的目标
需要header这样
“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"
}]
在 RxDataSources 的 example 中,我们有:
Observable.just(sections)
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
您需要做的就是将 Observable.just(sections) 替换为绑定到您的数据的 Observable。假设 notifications
是一个 Observable<[Notifications]>
。然后你做这样的事情:
notifications.map { sections(from: [=11=]) }
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
sections(from: [=17=])
是[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) { ([=13=], ) }
.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
}
}
我找到答案了
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
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
}
}