Заполнять объекты в разделах TableView по месяцам

У меня есть массив объектов, содержащих свойство Date. Я хочу распределить их в разделах UITableView в соответствии с их ежемесячным порядком. Как я могу это сделать?

Моя модель:

class Birthday: Object {
    @objc dynamic var name: String = ""
    @objc dynamic var date: Date = Date()
    @objc dynamic var dayLeft: Int = 0
    @objc dynamic var userImageData: Data?
}

Сначала я использую следующий код с DateFormatter:

var grouped: [String: [Birthday]] = [:]

grouped = Dictionary(grouping: birthdaysList) { item -> String in
    let calendar = Calendar.current
    let components = calendar.dateComponents([.year, .month], from: item.date)
    let date = calendar.date(from: components) ?? Date(timeIntervalSince1970: 0)
    return date.monthAsString()
}

extension Date {
    func monthAsString() -> String {
            let df = DateFormatter()
            df.setLocalizedDateFormatFromTemplate("MMM")
            return df.string(from: self)
    }
}

Затем я использую:

struct Section {
    let month: String
    let birthdays: [Birthday]
}

    var sections: [Section] = []
    let keys = Array(grouped.keys)
    sections = keys.map({Section(month: $0, birthdays: grouped[$0]!)})

Но мне нужно отсортировать названия месяцев по порядку. Январь, февраль и т.д. Как это можно сделать?

Я пытаюсь вернуть кортеж из своего кода, но получаю ошибку

Объявленный результат закрытия "(String, Int)" несовместим с контекстным типом "String"

grouped = Dictionary(grouping: birthdaysList) { item -> (String, Int) in
    let calendar = Calendar.current
    let components = calendar.dateComponents([.year, .month], from: item.date)
    let date = calendar.date(from: components) ?? Date(timeIntervalSince1970: 0)
    return (date.monthAsString(), components.month!)
}

Связанный: stackoverflow.com/questions/52043162/…

vadian 23.12.2020 21:22

Спасибо. Но, может быть, вы можете предоставить пример кода для моего случая?

Parcker 23.12.2020 21:31

На самом деле связанный ответ содержит пример. Сгруппируйте массив в словарь по году и месяцу.

vadian 23.12.2020 21:36

Я добавил к моему примеру кода вопроса, который вы предоставили, но все равно не могу понять, как получить названия месяцев в разделах.

Parcker 23.12.2020 21:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
90
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Создайте структуру-оболочку

struct Section {
    let month : String
    let birthdays : [Birthday]
}

затем сопоставьте сгруппированный словарь с массивом Section

let keys = Array(grouped.keys)
let sections = keys.map({Section(month: $0, birthdays: grouped[$0]!)})

sections представляют разделы, birthdays строки, month заголовки разделов.


Редактировать:

Чтобы иметь возможность сортировать месяцы по их порядковому номеру, верните число перед названием месяца.

grouped = Dictionary(grouping: birthdaysList) { item -> String in
    let calendar = Calendar.current
    let components = calendar.dateComponents([.year, .month], from: item.date)
    let date = calendar.date(from: components) ?? Date(timeIntervalSince1970: 0)
    return  "\(components.month!)_" + date.monthAsString()
}

И измените код сопоставления

let keys = grouped.keys.sorted{$0.localizedStandardCompare($1) == .orderedAscending}
let sections = keys.map({Section(month: $0.components(separatedBy:"_").last!, birthdays: grouped[$0]!)})

Я получаю сообщение об ошибке: Не удается преобразовать значение типа «[Любой]» в ожидаемый тип аргумента «[День рождения]»

Parcker 23.12.2020 23:07

Используйте собственные типы коллекций Swift.

vadian 23.12.2020 23:08

Что это значит?

Parcker 23.12.2020 23:11

Ошибка не связана с данным кодом, возможно, вы где-то использовали NSArray или забыли правильно преобразовать тип.

vadian 23.12.2020 23:13

Но как я могу отсортировать месяцы по порядку? Я хочу, чтобы сначала был январь, затем февраль и т. д. Как это можно сделать?

Parcker 24.12.2020 09:20

Вместо того, чтобы возвращать строку, верните кортеж (String, Int) из замыкания. Целочисленное значение является компонентом month, тогда вы сможете правильно отсортировать массив.

vadian 24.12.2020 09:39

Я пытаюсь, получаю ошибку: объявленный результат закрытия "(String, Int)" несовместим с контекстным типом "String"

Parcker 24.12.2020 09:49

Если вы заявляете item -> (String, Int) in, вы должны вернуть return (date.monthAsString(), components.month!) и наоборот.

vadian 24.12.2020 10:15

Я пытаюсь, но все равно получаю ошибку: Объявленный результат закрытия "(String, Int)" несовместим с контекстным типом "String"

Parcker 24.12.2020 10:24

Добавил информацию к вопросу. В сгруппированном = Словарь (группировка: список дней рождения)

Parcker 24.12.2020 10:27

Другие вопросы по теме