변경 사항 - 아주 멋진 작은 프로젝트
- 조엘 레빈
이것은 Dave Delong의 기사, 편집 거리 및 편집 단계에 요약 된 솔루션을 구현하려는 시도입니다.
Changeset 한 컬렉션의 Equatable 요소 Collection 에서 다른 요소로 이동하는 데 필요한 최소한의 편집을 설명합니다.
주로 두 개의 데이터 세트 사이의 추가, 삭제, 대체 및 이동을 감지하여 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 직접 호출 할 수 있습니다 (여기서는 iOS 용 Apple의 Table View 프로그래밍 안내서의 예제 데이터와 함께) :
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]ChangeET은 지수가 아닌 오프셋을 사용하여 컬렉션의 요소를 참조합니다. 이는 주로 신속한 컬렉션이 제로 기반 정수 지수를 사용하도록 보장되지 않기 때문입니다. 자세한 내용은 문제 #37의 토론을 참조하십시오.
오프셋 값은 UITableView 의 beginUpdates / endUpdates 의 애니메이션 블록 및 UICollectionView 의 performBatchUpdates 의 애니메이션 블록에서 직접 사용할 수 있습니다. Changeset 은 Apple Guide의 행 및 섹션의 배치 삽입, 삭제 및 재 장전 하에 설명 된 원칙을 따릅니다.
요컨대; 먼저 소스 컬렉션에 비해 모든 삭제 및 대체물이 결과 수집, 삽입에 비해 이루어집니다. 움직임은 삭제에 이어 삽입 일뿐입니다.
iOS 프레임 워크에서 애니메이션 테이블/컬렉션보기 업데이트를 산들 바람으로 만들기 위해 두 가지 편의 확장 ( UITableView 와 UICollectionView 에 하나)이 포함되었습니다. 다음과 같은 update 만 호출하십시오.
tableView . update ( with : changeset . edits ) 기본적으로 Changeset == 사용하여 요소를 비교하지만 아래 그림에 표시된 자체 비교기를 작성할 수 있습니다. 여기서 "A"의 발생은 항상 변경 사항을 유발합니다.
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 )결과적으로 변경 사항은 "A"(다른 "A"로)를 대체하는 것으로 구성됩니다.
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. 라이센스 파일을 참조하십시오.