Изменения - довольно потрясающий маленький проект
- Джоэл Левин
Это попытка реализовать решение, изложенное в статье Дейва Делонга, редактирования расстояния и редактирования шагов.
Changeset описывается минимальные изменения, необходимые для перехода от одной Collection Equatable элементов к другому.
Он был написан в первую очередь для использования в сочетании с источниками данных UITableView и UICollectionView путем обнаружения дополнений, удалений, замен и перемещений между двумя наборами данных. Но его также можно использовать для вычисления более общих изменений между двумя наборами данных.
Следующий код вычисляет минимальные изменения канонического примера, переходя от «котенка» в String коллекциях к «сидям»:
let changeset = Changeset ( source : " kitten " , target : " sitting " )
print ( changeset )
// 'kitten' -> 'sitting':
// replace with s at offset 0
// replace with i at offset 4
// insert g at offset 6Следующее утверждение тогда получит успех:
let edits = [
Changeset < String > . Edit ( operation : . substitution , value : " s " , destination : 0 ) ,
Changeset < String > . Edit ( operation : . substitution , value : " i " , destination : 4 ) ,
Changeset < String > . Edit ( operation : . insertion , value : " g " , destination : 6 ) ,
]
assert ( changeset . edits == edits ) Если вам не нужны накладные расходы самого Changeset , в котором также хранится коллекции источников и целевых, вы можете напрямую edits (здесь с примерами данных из Руководства по программированию таблицы Apple для iOS):
let source = [ " Arizona " , " California " , " Delaware " , " New Jersey " , " Washington " ]
let target = [ " Alaska " , " Arizona " , " California " , " Georgia " , " New Jersey " , " Virginia " ]
let edits = Changeset . edits ( from : source , to : target )
print ( edits )
// [insert Alaska at offset 0, replace with Georgia at offset 2, replace with Virginia at offset 4]Обратите внимание, что изменения в изменениях используют смещения, а не индексы, для обозначения элементов в коллекциях. Это происходит главным образом потому, что Swift Collections не гарантированно использует целочисленные индексы на основе нуля. Смотрите обсуждение в выпуске № 37 для получения более подробной информации.
Значения смещения могут использоваться непосредственно в анимационных блоках beginUpdates / endUpdates на UITableView и performBatchUpdates на UICollectionView в том, что Changeset следует принципам, объясненным под пакетной вставкой, удалением и перезагрузкой строк и разделов в руководстве Apple.
Суммируя; Сначала сделаны все удаления и замены относительно коллекции источников, а затем относительно полученной коллекции, вставки. Движение - это всего лишь удаление, за которым следует вставка.
В рамках iOS были включены два удобства (одно на UITableView и одно на UICollectionView ) для создания анимированных обновлений таблицы/коллекции. Просто позвоните update , например,:
tableView . update ( with : changeset . edits ) По умолчанию Changeset использует == для сравнения элементов, но вы можете написать свой собственный компаратор, показанный ниже, где происшествие «А» всегда запускает изменение:
let alwaysChangeA : ( Character , Character ) -> Bool = {
if $0 == " a " || $1 == " a " {
return false
} else {
return $0 == $1
}
}
let changeset = Changeset ( source : " ab " , target : " ab " , comparator : alwaysChangeA )В результате, набор изменений будет состоять из замены «А» (на другой «А»):
let expectedEdits : [ Changeset < String > . Edit ] = [ Changeset . Edit ( operation : . substitution , value : " a " , destination : 0 ) ]
assert ( changeset . edits == expectedEdits ) Одним из возможных использования этого является то, что ячейка в UITableView или UICollectionView не должна оживить, когда они меняются.
Проект XCode также содержит цель для иллюстрации использования в приложении:

Это использует расширения, упомянутые выше, для анимирования переходов на основе редактирования Changeset .
Этот проект доступен по лицензии MIT.
Copyright © 2015-18, Joachim Bondo. См. Файл лицензии.