diff --git a/README.md b/README.md index d71b136..e670c20 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The first thing (found in `Dwifft.swift`) is an algorithm that calculates the di The second thing (found in `Dwifft+UIKit.swift`) is a series of diff calculators for `UITableView`s and `UICollectionView`s. Let's say you have a `UITableView` that's backed by a simple array of values (like a list of names, e.g. `["Alice", "Bob", "Carol"]`. If that array changes (maybe Bob leaves, and is replaced by Dave, so our list is now `["Alice, "Carol", "Dave"]`), we'll want to update the table. The easiest way to do this is by calling `reloadData` on it. This has a couple of downsides: the transition isn't animated, and it'll cause your user to lose their scroll position if they've scrolled the table. The nicer way is to use the `insertRowsAtIndexPaths:withRowAnimation` and `deleteRowsAtIndexPaths:withRowAnimation` methods on `UITableView`, but this requires you to figure out which index paths have changed in your array (in our example, you'd have to figure out that the row at index 1 should be removed, and a new row should be inserted at index 2 should then be added). If only we had a way to diff the previous value of our array with it's new value. Wait a minute. -When you wire up a `TableViewDiffCalculator` to your `UITableView` (or a `CollectionViewDiffCalculator` to your `UICollectionView`, it'll _automatically_ calculate diffs and trigger the necessary animations on it whenever you change its `sectionedValues` property. Neat, right? Notably, as of Dwifft 0.6, Dwifft will also figure out _section_ insertions and deletions, as well as how to efficiently insert and delete rows across different sections, which is just so massively useful if you have a multi-section table. If you're currently using a <0.6 version of Dwifft and want to do this, read the [0.6 release notes](TODO). +When you wire up a `TableViewDiffCalculator` to your `UITableView` (or a `CollectionViewDiffCalculator` to your `UICollectionView`, it'll _automatically_ calculate diffs and trigger the necessary animations on it whenever you change its `sectionedValues` property. Neat, right? Notably, as of Dwifft 0.6, Dwifft will also figure out _section_ insertions and deletions, as well as how to efficiently insert and delete rows across different sections, which is just so massively useful if you have a multi-section table. If you're currently using a <0.6 version of Dwifft and want to do this, read the [0.6 release notes](https://github.com/jflinter/Dwifft/releases/tag/0.6). Even longer version --- @@ -32,12 +32,12 @@ Why you should use Dwifft How to get started --- - First, you should take a look at the example app, to get a feel for how Dwifft is meant to be used. -- Next, you should just sit down and read the [entire documentation](TODO) - it will take you <10 minutes, and you'll leave knowing everything there is to know about Dwifft. +- Next, you should just sit down and read the [entire documentation](https://jackflintermann.com/Dwifft) - it will take you <10 minutes, and you'll leave knowing everything there is to know about Dwifft. - Then, install Dwifft via cocoapods or carthage or whatever people are using these days. - Then get to Dwiffing. Contributing --- -Contributions are welcome, with some caveats - please read the [contributing guidelines](TODO) before opening a PR to avoid wasting both our time. +Contributions are welcome, with some caveats - please read the [contributing guidelines](https://github.com/jflinter/Dwifft/blob/master/CONTRIBUTING.md) before opening a PR to avoid wasting both our time. Ok, that's it, there's nothing more here. \ No newline at end of file diff --git a/docs/Typealiases.html b/docs/Typealiases.html index d775e14..555d280 100644 --- a/docs/Typealiases.html +++ b/docs/Typealiases.html @@ -100,9 +100,9 @@

Typealiases

  • - - - SimpleCollectionViewDiffCalculator + + + SimpleTableViewDiffCalculator
    @@ -110,14 +110,20 @@

    Typealiases

    -

    See SimpleTableViewDiffCalculator for explanation

    +

    Let’s say your data model consists of different sections containing different model types. Since +SectionedValues requires a uniform type for all of its rows, this can be a clunky situation. You +can address this in a couple of ways. The first is to define a custom enum that encompasses all of the +things that could be in your data model - if section 1 has a bunch of Strings, and section 2 has a bunch +of Ints, define a StringOrInt enum that conforms to Equatable, and fill the SectionedValues +that you use to drive your DiffCalculator up with those. Alternatively, if you are lazy, and your +models all conform to Hashable, you can use a SimpleTableViewDiffCalculator instead.

    Declaration

    Swift

    -
    typealias SimpleCollectionViewDiffCalculator = CollectionViewDiffCalculator<AnyHashable, AnyHashable>
    +
    typealias SimpleTableViewDiffCalculator = TableViewDiffCalculator<AnyHashable, AnyHashable>
    @@ -127,9 +133,9 @@

    Declaration

  • - - - SimpleTableViewDiffCalculator + + + SimpleCollectionViewDiffCalculator
    @@ -137,20 +143,14 @@

    Declaration

    -

    Let’s say your data model consists of different sections containing different model types. Since -SectionedValues requires a uniform type for all of its rows, this can be a clunky situation. You -can address this in a couple of ways. The first is to define a custom enum that encompasses all of the -things that could be in your data model - if section 1 has a bunch of Strings, and section 2 has a bunch -of Ints, define a StringOrInt enum that conforms to Equatable, and fill the SectionedValues -that you use to drive your DiffCalculator up with those. Alternatively, if you are lazy, and your -models all conform to Hashable, you can use a SimpleTableViewDiffCalculator instead.

    +

    See SimpleTableViewDiffCalculator for explanation

    Declaration

    Swift

    -
    typealias SimpleTableViewDiffCalculator = TableViewDiffCalculator<AnyHashable, AnyHashable>
    +
    typealias SimpleCollectionViewDiffCalculator = CollectionViewDiffCalculator<AnyHashable, AnyHashable>
    diff --git a/docs/docsets/Dwifft.docset/Contents/Resources/Documents/Typealiases.html b/docs/docsets/Dwifft.docset/Contents/Resources/Documents/Typealiases.html index d775e14..555d280 100644 --- a/docs/docsets/Dwifft.docset/Contents/Resources/Documents/Typealiases.html +++ b/docs/docsets/Dwifft.docset/Contents/Resources/Documents/Typealiases.html @@ -100,9 +100,9 @@

    Typealiases

  • @@ -110,14 +110,20 @@

    Typealiases

    -

    See SimpleTableViewDiffCalculator for explanation

    +

    Let’s say your data model consists of different sections containing different model types. Since +SectionedValues requires a uniform type for all of its rows, this can be a clunky situation. You +can address this in a couple of ways. The first is to define a custom enum that encompasses all of the +things that could be in your data model - if section 1 has a bunch of Strings, and section 2 has a bunch +of Ints, define a StringOrInt enum that conforms to Equatable, and fill the SectionedValues +that you use to drive your DiffCalculator up with those. Alternatively, if you are lazy, and your +models all conform to Hashable, you can use a SimpleTableViewDiffCalculator instead.

    Declaration

    Swift

    -
    typealias SimpleCollectionViewDiffCalculator = CollectionViewDiffCalculator<AnyHashable, AnyHashable>
    +
    typealias SimpleTableViewDiffCalculator = TableViewDiffCalculator<AnyHashable, AnyHashable>
    @@ -127,9 +133,9 @@

    Declaration

  • @@ -137,20 +143,14 @@

    Declaration

    -

    Let’s say your data model consists of different sections containing different model types. Since -SectionedValues requires a uniform type for all of its rows, this can be a clunky situation. You -can address this in a couple of ways. The first is to define a custom enum that encompasses all of the -things that could be in your data model - if section 1 has a bunch of Strings, and section 2 has a bunch -of Ints, define a StringOrInt enum that conforms to Equatable, and fill the SectionedValues -that you use to drive your DiffCalculator up with those. Alternatively, if you are lazy, and your -models all conform to Hashable, you can use a SimpleTableViewDiffCalculator instead.

    +

    See SimpleTableViewDiffCalculator for explanation

    Declaration

    Swift

    -
    typealias SimpleTableViewDiffCalculator = TableViewDiffCalculator<AnyHashable, AnyHashable>
    +
    typealias SimpleCollectionViewDiffCalculator = CollectionViewDiffCalculator<AnyHashable, AnyHashable>
    diff --git a/docs/docsets/Dwifft.docset/Contents/Resources/Documents/index.html b/docs/docsets/Dwifft.docset/Contents/Resources/Documents/index.html index 312f0dd..093b459 100644 --- a/docs/docsets/Dwifft.docset/Contents/Resources/Documents/index.html +++ b/docs/docsets/Dwifft.docset/Contents/Resources/Documents/index.html @@ -91,29 +91,45 @@
    -

    Build Status +

    Build Status Current Version

    Dwifft!

    +

    In 10 seconds

    -

    OK. Dwifft is a Swift library that does two things. The first thing sounds interesting but perhaps only abstractly useful, and the other thing is a very concretely useful thing based off the first thing.

    +

    Dwifft is a small Swift library that tells you what the diff is between two collections, namely, the series of edit operations required to turn one into the other. It also comes with UIKit bindings, to automatically, animatedly keep a UITableView/UICollectionView in sync with a piece of data by making the necessary row/section insertion/deletion calls for you as the data changes.

    +

    Longer version

    -

    The first thing (found in Dwifft.swift) is an algorithm that solves the Longest Common Subsequence problem. Pragmatically, the problem of finding the difference between two arrays is trivially reducable to the LCS problem, i.e. if you can find the longest common subsequence between two arrays, you’ve also found a series of transforms to apply to array 1 that will result in array 2. This algorithm is written purely in Swift, and uses dynamic programming to achieve substantial performance improvements over a naïve approach (that being said, there are several ways it could probably be sped up.) Perhaps by now you’ve figured out that Dwifft is a terrible/brilliant portmanteau of Swift and Diff. If this kind of thing is interesting to you, there’s a pretty great paper on diffing algorithms: http://www.xmailserver.org/diff2.pdf

    +

    Dwifft is a Swift library that does two things. The first thing sounds interesting but perhaps only abstractly useful, and the other thing is a very concretely useful thing based off the first thing.

    + +

    The first thing (found in Dwifft.swift) is an algorithm that calculates the diff between two collections using the Longest Common Subsequence method. If this kind of thing is interesting to you, there’s a pretty great paper on diffing algorithms: http://www.xmailserver.org/diff2.pdf

    The second thing (found in Dwifft+UIKit.swift) is a series of diff calculators for UITableViews and UICollectionViews. Let’s say you have a UITableView that’s backed by a simple array of values (like a list of names, e.g. ["Alice", "Bob", "Carol"]. If that array changes (maybe Bob leaves, and is replaced by Dave, so our list is now ["Alice, "Carol", "Dave"]), we’ll want to update the table. The easiest way to do this is by calling reloadData on it. This has a couple of downsides: the transition isn’t animated, and it’ll cause your user to lose their scroll position if they’ve scrolled the table. The nicer way is to use the insertRowsAtIndexPaths:withRowAnimation and deleteRowsAtIndexPaths:withRowAnimation methods on UITableView, but this requires you to figure out which index paths have changed in your array (in our example, you’d have to figure out that the row at index 1 should be removed, and a new row should be inserted at index 2 should then be added). If only we had a way to diff the previous value of our array with it’s new value. Wait a minute.

    -

    When you wire up a TableViewDiffCalculator to your UITableView (or a CollectionViewDiffCalculator to your UICollectionView, it’ll automatically calculate diffs and trigger the necessary animations on it whenever you change its rows property. Neat, right? Usually, this rows object will be the same thing you’re using in your UITableViewDataSource methods. The only constraint is that the items in that rows array have to conform to Equatable, because, you know, how else could you compare them?

    +

    When you wire up a TableViewDiffCalculator to your UITableView (or a CollectionViewDiffCalculator to your UICollectionView, it’ll automatically calculate diffs and trigger the necessary animations on it whenever you change its sectionedValues property. Neat, right? Notably, as of Dwifft 0.6, Dwifft will also figure out section insertions and deletions, as well as how to efficiently insert and delete rows across different sections, which is just so massively useful if you have a multi-section table. If you’re currently using a <0.6 version of Dwifft and want to do this, read the 0.6 release notes.

    +

    Even longer version

    -

    This makes slightly more sense in code, so check out the tests (which show LCS/Diff in action) and the example app (which demonstrates the use of TableViewDiffCalculator). You can quickly run the example with pod try Dwifft.

    +

    Learn more about the history of Dwifft, and how it works, in this exciting video of a talk recorded at the Brooklyn Swift meetup in March 2017.

    +

    Why you should use Dwifft

    -

    Thanks for reading! PRs and such are of course welcome, but I want to keep this pretty tightly-scoped, so I’d politely request you open an issue before going off and implementing any new functionality so we can talk things over first.

    +
      +
    • Dwifft is useful - it can help you build a substantially better user experience if you have table/collection views with dynamic content in your app.
    • +
    • Dwifft is safe - there is some non-trivial index math inside of this diff algorithm that is easy to screw up. Dwifft has 100% test coverage on all of its core algorithms. Additionally, all of Dwifft’s core functionality is tested with SwiftCheck, meaning it has been shown to behave correctly under an exhausting set of inputs and edge cases.
    • +
    • Dwifft is fast - a lot of time has been spent making Dwifft considerably (many orders of magnitude) faster than a naïve implementation. It almost certainly won’t be the bottleneck in your UI code.
    • +
    • Dwifft is small - Dwifft believes (to the extent that a software library can believe in things) in the unix philosophy of small, easily-composed tools. It’s unopinionated and flexible enough to fit into most apps, and leaves a lot of control in your hands as a developer. As such, you can probably cram it into your app in less than 5 minutes. Also, because it’s small, it can actually achieve nice goals like 100% test and documentation coverage.
    • +
    +

    How to get started

    -

    Happy dwiffing!

    -

    Oh right, how to install

    +
      +
    • First, you should take a look at the example app, to get a feel for how Dwifft is meant to be used.
    • +
    • Next, you should just sit down and read the entire documentation - it will take you <10 minutes, and you’ll leave knowing everything there is to know about Dwifft.
    • +
    • Then, install Dwifft via cocoapods or carthage or whatever people are using these days.
    • +
    • Then get to Dwiffing.
    • +
    +

    Contributing

    -

    Cocoapods or Carthage. You’ll need to use cocoapods frameworks because Swift. Version 0.1 is written in Swift 1.2, versions 0.2-0.3.1 are Swift 2, beyond that is Swift 3.

    -

    A fun gif

    +

    Contributions are welcome, with some caveats - please read the contributing guidelines before opening a PR to avoid wasting both our time.

    -

    Dwifft

    +

    Ok, that’s it, there’s nothing more here.

    diff --git a/docs/docsets/Dwifft.docset/Contents/Resources/Documents/search.json b/docs/docsets/Dwifft.docset/Contents/Resources/Documents/search.json index c22006b..5305ba3 100644 --- a/docs/docsets/Dwifft.docset/Contents/Resources/Documents/search.json +++ b/docs/docsets/Dwifft.docset/Contents/Resources/Documents/search.json @@ -1 +1 @@ -{"Typealiases.html#/s:6Dwifft34SimpleCollectionViewDiffCalculator":{"name":"SimpleCollectionViewDiffCalculator","abstract":"

    See SimpleTableViewDiffCalculator for explanation

    "},"Typealiases.html#/s:6Dwifft29SimpleTableViewDiffCalculator":{"name":"SimpleTableViewDiffCalculator","abstract":"

    Let’s say your data model consists of different sections containing different model types. Since"},"Structs/SectionedValues.html#/s:FV6Dwifft15SectionedValuescFGSaTxGSaq____GS0_xq__":{"name":"init(_:)","abstract":"

    Initializes the struct with an array of key-pairs.

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:vV6Dwifft15SectionedValues17sectionsAndValuesGSaTxGSaq____":{"name":"sectionsAndValues","abstract":"

    The underlying tuples contained in the receiver

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:FV6Dwifft15SectionedValues9appendingFT15sectionAndValueTxGSaq____GS0_xq__":{"name":"appending(sectionAndValue:)","abstract":"

    Returns a new SectionedValues appending a new key-value pair. I think this might be useful","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:ZFV6Dwifft15SectionedValuesoi2eeFTGS0_xq__GS0_xq___Sb":{"name":"==(_:_:)","abstract":"

    Compares two SectionedValues instances

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:Fe6Dwifft0_Rxs8Hashable_s9EquatablerVS_15SectionedValuescFT6valuesGSaq__14valueToSectionFq_x12sortSectionsFTxx_Sb10sortValuesFTq_q__Sb_GS2_xq__":{"name":"init(values:valueToSection:sortSections:sortValues:)","abstract":"

    This is a convenience initializer of sorts for SectionedValues. It acknowledges","parent_name":"SectionedValues"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft4diffuRxs9EquatablerFTGSax_GSax__GSaGOS_8DiffStepx__":{"name":"diff(_:_:)","abstract":"

    Returns the sequence of DiffSteps required to transform one array into another.

    ","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft5applyurFT4diffGSaGOS_8DiffStepx__7toArrayGSax__GSax_":{"name":"apply(diff:toArray:)","abstract":"

    Applies a diff to an array. The following should always be true:","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft4diffu0_Rxs9Equatable_S1_rFT3lhsGVS_15SectionedValuesxq__3rhsGS2_xq___GSaGOS_17SectionedDiffStepxq___":{"name":"diff(lhs:rhs:)","abstract":"

    Returns the sequence of SectionedDiffSteps required to transform one SectionedValues into another.

    ","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft5applyu0_Rxs9Equatable_S1_rFT4diffGSaGOS_17SectionedDiffStepxq___17toSectionedValuesGVS_15SectionedValuesxq___GS3_xq__":{"name":"apply(diff:toSectionedValues:)","abstract":"

    Applies a diff to a SectionedValues. The following should always be true:","parent_name":"Dwifft"},"Structs/Dwifft.html":{"name":"Dwifft","abstract":"

    Namespace for the diff and apply functions.

    "},"Structs/SectionedValues.html":{"name":"SectionedValues","abstract":"

    SectionedValues represents, well, a bunch of sections and their associated values."},"Extensions/Array.html#/s:Fe6DwifftRxs9EquatablerSa4diffFGSax_GSaGOS_8DiffStepx__":{"name":"diff(_:)","abstract":"

    Deprecated in favor of Dwifft.diff.

    ","parent_name":"Array"},"Extensions/Array.html#/s:Fe6DwifftRxs9EquatablerSa5applyFGSaGOS_8DiffStepx__GSax_":{"name":"apply(_:)","abstract":"

    Deprecated in favor of Dwifft.apply.

    ","parent_name":"Array"},"Extensions/Array.html":{"name":"Array"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep6insertu0_rFMGS0_xq__FTSiSiq__GS0_xq__":{"name":"insert","abstract":"

    An insertion, at a given section and row.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep6deleteu0_rFMGS0_xq__FTSiSiq__GS0_xq__":{"name":"delete","abstract":"

    An deletion, at a given section and row.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep13sectionInsertu0_rFMGS0_xq__FTSix_GS0_xq__":{"name":"sectionInsert","abstract":"

    A section insertion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep13sectionDeleteu0_rFMGS0_xq__FTSix_GS0_xq__":{"name":"sectionDelete","abstract":"

    A section deletion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:vPs28CustomDebugStringConvertible16debugDescriptionSS":{"name":"debugDescription","abstract":"

    A section deletion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/DiffStep.html#/s:FO6Dwifft8DiffStep6inserturFMGS0_x_FTSix_GS0_x_":{"name":"insert","abstract":"

    An insertion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:FO6Dwifft8DiffStep6deleteurFMGS0_x_FTSix_GS0_x_":{"name":"delete","abstract":"

    A deletion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vPs28CustomDebugStringConvertible16debugDescriptionSS":{"name":"debugDescription","abstract":"

    A deletion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vO6Dwifft8DiffStep3idxSi":{"name":"idx","abstract":"

    The index to be inserted or deleted.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vO6Dwifft8DiffStep5valuex":{"name":"value","abstract":"

    The value to be inserted or deleted.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html":{"name":"DiffStep","abstract":"

    These get returned from calls to Dwifft.diff(). They represent insertions or deletions"},"Enums/SectionedDiffStep.html":{"name":"SectionedDiffStep","abstract":"

    These get returned from calls to Dwifft.diff(). They represent insertions or deletions"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator14collectionViewXwGSqCSo16UICollectionView_":{"name":"collectionView","abstract":"

    The collection view to be managed

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator12sectionIndexSi":{"name":"sectionIndex","abstract":"

    All insertion/deletion calls will be made for items at this section.

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator5itemsGSax_":{"name":"items","abstract":"

    Set this variable to automatically trigger the correct item insertion/deletions","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:FC6Dwifft41SingleSectionCollectionViewDiffCalculatorcFT14collectionViewGSqCSo16UICollectionView_12initialItemsGSax_12sectionIndexSi_GS0_x_":{"name":"init(collectionView:initialItems:sectionIndex:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator9tableViewXwGSqCSo11UITableView_":{"name":"tableView","abstract":"

    The table view to be managed

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator12sectionIndexSi":{"name":"sectionIndex","abstract":"

    All insertion/deletion calls will be made on this index.

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator18insertionAnimationOSC23UITableViewRowAnimation":{"name":"insertionAnimation","abstract":"

    You can change insertion/deletion animations like this! Fade works well.","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator4rowsGSax_":{"name":"rows","abstract":"

    Set this variable to automatically trigger the correct row insertion/deletions","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:FC6Dwifft36SingleSectionTableViewDiffCalculatorcFT9tableViewGSqCSo11UITableView_11initialRowsGSax_12sectionIndexSi_GS0_x_":{"name":"init(tableView:initialRows:sectionIndex:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/CollectionViewDiffCalculator.html#/s:vC6Dwifft28CollectionViewDiffCalculator14collectionViewXwGSqCSo16UICollectionView_":{"name":"collectionView","abstract":"

    The collection view to be managed.

    ","parent_name":"CollectionViewDiffCalculator"},"Classes/CollectionViewDiffCalculator.html#/s:FC6Dwifft28CollectionViewDiffCalculatorcFT14collectionViewGSqCSo16UICollectionView_22initialSectionedValuesGVS_15SectionedValuesxq___GS0_xq__":{"name":"init(collectionView:initialSectionedValues:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"CollectionViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:vC6Dwifft23TableViewDiffCalculator9tableViewXwGSqCSo11UITableView_":{"name":"tableView","abstract":"

    The table view to be managed

    ","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:FC6Dwifft23TableViewDiffCalculatorcFT9tableViewGSqCSo11UITableView_22initialSectionedValuesGVS_15SectionedValuesxq___GS0_xq__":{"name":"init(tableView:initialSectionedValues:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:vC6Dwifft23TableViewDiffCalculator18insertionAnimationOSC23UITableViewRowAnimation":{"name":"insertionAnimation","abstract":"

    You can change insertion/deletion animations like this! Fade works well.","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html":{"name":"TableViewDiffCalculator","abstract":"

    This class manages a UITableView’s rows and sections. It will make the necessary calls to"},"Classes/CollectionViewDiffCalculator.html":{"name":"CollectionViewDiffCalculator","abstract":"

    This class manages a UICollectionView’s items and sections. It will make the necessary"},"Classes/SingleSectionTableViewDiffCalculator.html":{"name":"SingleSectionTableViewDiffCalculator","abstract":"

    If your table view only has a single section, or you only want to power a single section of it with Dwifft,"},"Classes/SingleSectionCollectionViewDiffCalculator.html":{"name":"SingleSectionCollectionViewDiffCalculator","abstract":"

    If your collection view only has a single section, or you only want to power a single section of it with Dwifft,"},"Classes.html":{"name":"Classes","abstract":"The following classes are available globally."},"Enums.html":{"name":"Enums","abstract":"The following enums are available globally."},"Extensions.html":{"name":"Extensions","abstract":"The following extensions are available globally."},"Structs.html":{"name":"Structs","abstract":"The following structs are available globally."},"Typealiases.html":{"name":"Typealiases","abstract":"The following typealiases are available globally."}} \ No newline at end of file +{"Typealiases.html#/s:6Dwifft29SimpleTableViewDiffCalculator":{"name":"SimpleTableViewDiffCalculator","abstract":"

    Let’s say your data model consists of different sections containing different model types. Since"},"Typealiases.html#/s:6Dwifft34SimpleCollectionViewDiffCalculator":{"name":"SimpleCollectionViewDiffCalculator","abstract":"

    See SimpleTableViewDiffCalculator for explanation

    "},"Structs/SectionedValues.html#/s:FV6Dwifft15SectionedValuescFGSaTxGSaq____GS0_xq__":{"name":"init(_:)","abstract":"

    Initializes the struct with an array of key-pairs.

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:vV6Dwifft15SectionedValues17sectionsAndValuesGSaTxGSaq____":{"name":"sectionsAndValues","abstract":"

    The underlying tuples contained in the receiver

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:FV6Dwifft15SectionedValues9appendingFT15sectionAndValueTxGSaq____GS0_xq__":{"name":"appending(sectionAndValue:)","abstract":"

    Returns a new SectionedValues appending a new key-value pair. I think this might be useful","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:ZFV6Dwifft15SectionedValuesoi2eeFTGS0_xq__GS0_xq___Sb":{"name":"==(_:_:)","abstract":"

    Compares two SectionedValues instances

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:Fe6Dwifft0_Rxs8Hashable_s9EquatablerVS_15SectionedValuescFT6valuesGSaq__14valueToSectionFq_x12sortSectionsFTxx_Sb10sortValuesFTq_q__Sb_GS2_xq__":{"name":"init(values:valueToSection:sortSections:sortValues:)","abstract":"

    This is a convenience initializer of sorts for SectionedValues. It acknowledges","parent_name":"SectionedValues"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft4diffuRxs9EquatablerFTGSax_GSax__GSaGOS_8DiffStepx__":{"name":"diff(_:_:)","abstract":"

    Returns the sequence of DiffSteps required to transform one array into another.

    ","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft5applyurFT4diffGSaGOS_8DiffStepx__7toArrayGSax__GSax_":{"name":"apply(diff:toArray:)","abstract":"

    Applies a diff to an array. The following should always be true:","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft4diffu0_Rxs9Equatable_S1_rFT3lhsGVS_15SectionedValuesxq__3rhsGS2_xq___GSaGOS_17SectionedDiffStepxq___":{"name":"diff(lhs:rhs:)","abstract":"

    Returns the sequence of SectionedDiffSteps required to transform one SectionedValues into another.

    ","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft5applyu0_Rxs9Equatable_S1_rFT4diffGSaGOS_17SectionedDiffStepxq___17toSectionedValuesGVS_15SectionedValuesxq___GS3_xq__":{"name":"apply(diff:toSectionedValues:)","abstract":"

    Applies a diff to a SectionedValues. The following should always be true:","parent_name":"Dwifft"},"Structs/Dwifft.html":{"name":"Dwifft","abstract":"

    Namespace for the diff and apply functions.

    "},"Structs/SectionedValues.html":{"name":"SectionedValues","abstract":"

    SectionedValues represents, well, a bunch of sections and their associated values."},"Extensions/Array.html#/s:Fe6DwifftRxs9EquatablerSa4diffFGSax_GSaGOS_8DiffStepx__":{"name":"diff(_:)","abstract":"

    Deprecated in favor of Dwifft.diff.

    ","parent_name":"Array"},"Extensions/Array.html#/s:Fe6DwifftRxs9EquatablerSa5applyFGSaGOS_8DiffStepx__GSax_":{"name":"apply(_:)","abstract":"

    Deprecated in favor of Dwifft.apply.

    ","parent_name":"Array"},"Extensions/Array.html":{"name":"Array"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep6insertu0_rFMGS0_xq__FTSiSiq__GS0_xq__":{"name":"insert","abstract":"

    An insertion, at a given section and row.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep6deleteu0_rFMGS0_xq__FTSiSiq__GS0_xq__":{"name":"delete","abstract":"

    An deletion, at a given section and row.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep13sectionInsertu0_rFMGS0_xq__FTSix_GS0_xq__":{"name":"sectionInsert","abstract":"

    A section insertion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep13sectionDeleteu0_rFMGS0_xq__FTSix_GS0_xq__":{"name":"sectionDelete","abstract":"

    A section deletion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:vPs28CustomDebugStringConvertible16debugDescriptionSS":{"name":"debugDescription","abstract":"

    A section deletion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/DiffStep.html#/s:FO6Dwifft8DiffStep6inserturFMGS0_x_FTSix_GS0_x_":{"name":"insert","abstract":"

    An insertion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:FO6Dwifft8DiffStep6deleteurFMGS0_x_FTSix_GS0_x_":{"name":"delete","abstract":"

    A deletion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vPs28CustomDebugStringConvertible16debugDescriptionSS":{"name":"debugDescription","abstract":"

    A deletion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vO6Dwifft8DiffStep3idxSi":{"name":"idx","abstract":"

    The index to be inserted or deleted.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vO6Dwifft8DiffStep5valuex":{"name":"value","abstract":"

    The value to be inserted or deleted.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html":{"name":"DiffStep","abstract":"

    These get returned from calls to Dwifft.diff(). They represent insertions or deletions"},"Enums/SectionedDiffStep.html":{"name":"SectionedDiffStep","abstract":"

    These get returned from calls to Dwifft.diff(). They represent insertions or deletions"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator14collectionViewXwGSqCSo16UICollectionView_":{"name":"collectionView","abstract":"

    The collection view to be managed

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator12sectionIndexSi":{"name":"sectionIndex","abstract":"

    All insertion/deletion calls will be made for items at this section.

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator5itemsGSax_":{"name":"items","abstract":"

    Set this variable to automatically trigger the correct item insertion/deletions","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:FC6Dwifft41SingleSectionCollectionViewDiffCalculatorcFT14collectionViewGSqCSo16UICollectionView_12initialItemsGSax_12sectionIndexSi_GS0_x_":{"name":"init(collectionView:initialItems:sectionIndex:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator9tableViewXwGSqCSo11UITableView_":{"name":"tableView","abstract":"

    The table view to be managed

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator12sectionIndexSi":{"name":"sectionIndex","abstract":"

    All insertion/deletion calls will be made on this index.

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator18insertionAnimationOSC23UITableViewRowAnimation":{"name":"insertionAnimation","abstract":"

    You can change insertion/deletion animations like this! Fade works well.","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator4rowsGSax_":{"name":"rows","abstract":"

    Set this variable to automatically trigger the correct row insertion/deletions","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:FC6Dwifft36SingleSectionTableViewDiffCalculatorcFT9tableViewGSqCSo11UITableView_11initialRowsGSax_12sectionIndexSi_GS0_x_":{"name":"init(tableView:initialRows:sectionIndex:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/CollectionViewDiffCalculator.html#/s:vC6Dwifft28CollectionViewDiffCalculator14collectionViewXwGSqCSo16UICollectionView_":{"name":"collectionView","abstract":"

    The collection view to be managed.

    ","parent_name":"CollectionViewDiffCalculator"},"Classes/CollectionViewDiffCalculator.html#/s:FC6Dwifft28CollectionViewDiffCalculatorcFT14collectionViewGSqCSo16UICollectionView_22initialSectionedValuesGVS_15SectionedValuesxq___GS0_xq__":{"name":"init(collectionView:initialSectionedValues:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"CollectionViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:vC6Dwifft23TableViewDiffCalculator9tableViewXwGSqCSo11UITableView_":{"name":"tableView","abstract":"

    The table view to be managed

    ","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:FC6Dwifft23TableViewDiffCalculatorcFT9tableViewGSqCSo11UITableView_22initialSectionedValuesGVS_15SectionedValuesxq___GS0_xq__":{"name":"init(tableView:initialSectionedValues:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:vC6Dwifft23TableViewDiffCalculator18insertionAnimationOSC23UITableViewRowAnimation":{"name":"insertionAnimation","abstract":"

    You can change insertion/deletion animations like this! Fade works well.","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html":{"name":"TableViewDiffCalculator","abstract":"

    This class manages a UITableView’s rows and sections. It will make the necessary calls to"},"Classes/CollectionViewDiffCalculator.html":{"name":"CollectionViewDiffCalculator","abstract":"

    This class manages a UICollectionView’s items and sections. It will make the necessary"},"Classes/SingleSectionTableViewDiffCalculator.html":{"name":"SingleSectionTableViewDiffCalculator","abstract":"

    If your table view only has a single section, or you only want to power a single section of it with Dwifft,"},"Classes/SingleSectionCollectionViewDiffCalculator.html":{"name":"SingleSectionCollectionViewDiffCalculator","abstract":"

    If your collection view only has a single section, or you only want to power a single section of it with Dwifft,"},"Classes.html":{"name":"Classes","abstract":"The following classes are available globally."},"Enums.html":{"name":"Enums","abstract":"The following enums are available globally."},"Extensions.html":{"name":"Extensions","abstract":"The following extensions are available globally."},"Structs.html":{"name":"Structs","abstract":"The following structs are available globally."},"Typealiases.html":{"name":"Typealiases","abstract":"The following typealiases are available globally."}} \ No newline at end of file diff --git a/docs/docsets/Dwifft.docset/Contents/Resources/docSet.dsidx b/docs/docsets/Dwifft.docset/Contents/Resources/docSet.dsidx index b55f8e4..e498a51 100644 Binary files a/docs/docsets/Dwifft.docset/Contents/Resources/docSet.dsidx and b/docs/docsets/Dwifft.docset/Contents/Resources/docSet.dsidx differ diff --git a/docs/docsets/Dwifft.tgz b/docs/docsets/Dwifft.tgz index cf94cfc..7652617 100644 Binary files a/docs/docsets/Dwifft.tgz and b/docs/docsets/Dwifft.tgz differ diff --git a/docs/index.html b/docs/index.html index 312f0dd..093b459 100644 --- a/docs/index.html +++ b/docs/index.html @@ -91,29 +91,45 @@

    -

    Build Status +

    Build Status Current Version

    Dwifft!

    +

    In 10 seconds

    -

    OK. Dwifft is a Swift library that does two things. The first thing sounds interesting but perhaps only abstractly useful, and the other thing is a very concretely useful thing based off the first thing.

    +

    Dwifft is a small Swift library that tells you what the diff is between two collections, namely, the series of edit operations required to turn one into the other. It also comes with UIKit bindings, to automatically, animatedly keep a UITableView/UICollectionView in sync with a piece of data by making the necessary row/section insertion/deletion calls for you as the data changes.

    +

    Longer version

    -

    The first thing (found in Dwifft.swift) is an algorithm that solves the Longest Common Subsequence problem. Pragmatically, the problem of finding the difference between two arrays is trivially reducable to the LCS problem, i.e. if you can find the longest common subsequence between two arrays, you’ve also found a series of transforms to apply to array 1 that will result in array 2. This algorithm is written purely in Swift, and uses dynamic programming to achieve substantial performance improvements over a naïve approach (that being said, there are several ways it could probably be sped up.) Perhaps by now you’ve figured out that Dwifft is a terrible/brilliant portmanteau of Swift and Diff. If this kind of thing is interesting to you, there’s a pretty great paper on diffing algorithms: http://www.xmailserver.org/diff2.pdf

    +

    Dwifft is a Swift library that does two things. The first thing sounds interesting but perhaps only abstractly useful, and the other thing is a very concretely useful thing based off the first thing.

    + +

    The first thing (found in Dwifft.swift) is an algorithm that calculates the diff between two collections using the Longest Common Subsequence method. If this kind of thing is interesting to you, there’s a pretty great paper on diffing algorithms: http://www.xmailserver.org/diff2.pdf

    The second thing (found in Dwifft+UIKit.swift) is a series of diff calculators for UITableViews and UICollectionViews. Let’s say you have a UITableView that’s backed by a simple array of values (like a list of names, e.g. ["Alice", "Bob", "Carol"]. If that array changes (maybe Bob leaves, and is replaced by Dave, so our list is now ["Alice, "Carol", "Dave"]), we’ll want to update the table. The easiest way to do this is by calling reloadData on it. This has a couple of downsides: the transition isn’t animated, and it’ll cause your user to lose their scroll position if they’ve scrolled the table. The nicer way is to use the insertRowsAtIndexPaths:withRowAnimation and deleteRowsAtIndexPaths:withRowAnimation methods on UITableView, but this requires you to figure out which index paths have changed in your array (in our example, you’d have to figure out that the row at index 1 should be removed, and a new row should be inserted at index 2 should then be added). If only we had a way to diff the previous value of our array with it’s new value. Wait a minute.

    -

    When you wire up a TableViewDiffCalculator to your UITableView (or a CollectionViewDiffCalculator to your UICollectionView, it’ll automatically calculate diffs and trigger the necessary animations on it whenever you change its rows property. Neat, right? Usually, this rows object will be the same thing you’re using in your UITableViewDataSource methods. The only constraint is that the items in that rows array have to conform to Equatable, because, you know, how else could you compare them?

    +

    When you wire up a TableViewDiffCalculator to your UITableView (or a CollectionViewDiffCalculator to your UICollectionView, it’ll automatically calculate diffs and trigger the necessary animations on it whenever you change its sectionedValues property. Neat, right? Notably, as of Dwifft 0.6, Dwifft will also figure out section insertions and deletions, as well as how to efficiently insert and delete rows across different sections, which is just so massively useful if you have a multi-section table. If you’re currently using a <0.6 version of Dwifft and want to do this, read the 0.6 release notes.

    +

    Even longer version

    -

    This makes slightly more sense in code, so check out the tests (which show LCS/Diff in action) and the example app (which demonstrates the use of TableViewDiffCalculator). You can quickly run the example with pod try Dwifft.

    +

    Learn more about the history of Dwifft, and how it works, in this exciting video of a talk recorded at the Brooklyn Swift meetup in March 2017.

    +

    Why you should use Dwifft

    -

    Thanks for reading! PRs and such are of course welcome, but I want to keep this pretty tightly-scoped, so I’d politely request you open an issue before going off and implementing any new functionality so we can talk things over first.

    +
      +
    • Dwifft is useful - it can help you build a substantially better user experience if you have table/collection views with dynamic content in your app.
    • +
    • Dwifft is safe - there is some non-trivial index math inside of this diff algorithm that is easy to screw up. Dwifft has 100% test coverage on all of its core algorithms. Additionally, all of Dwifft’s core functionality is tested with SwiftCheck, meaning it has been shown to behave correctly under an exhausting set of inputs and edge cases.
    • +
    • Dwifft is fast - a lot of time has been spent making Dwifft considerably (many orders of magnitude) faster than a naïve implementation. It almost certainly won’t be the bottleneck in your UI code.
    • +
    • Dwifft is small - Dwifft believes (to the extent that a software library can believe in things) in the unix philosophy of small, easily-composed tools. It’s unopinionated and flexible enough to fit into most apps, and leaves a lot of control in your hands as a developer. As such, you can probably cram it into your app in less than 5 minutes. Also, because it’s small, it can actually achieve nice goals like 100% test and documentation coverage.
    • +
    +

    How to get started

    -

    Happy dwiffing!

    -

    Oh right, how to install

    +
      +
    • First, you should take a look at the example app, to get a feel for how Dwifft is meant to be used.
    • +
    • Next, you should just sit down and read the entire documentation - it will take you <10 minutes, and you’ll leave knowing everything there is to know about Dwifft.
    • +
    • Then, install Dwifft via cocoapods or carthage or whatever people are using these days.
    • +
    • Then get to Dwiffing.
    • +
    +

    Contributing

    -

    Cocoapods or Carthage. You’ll need to use cocoapods frameworks because Swift. Version 0.1 is written in Swift 1.2, versions 0.2-0.3.1 are Swift 2, beyond that is Swift 3.

    -

    A fun gif

    +

    Contributions are welcome, with some caveats - please read the contributing guidelines before opening a PR to avoid wasting both our time.

    -

    Dwifft

    +

    Ok, that’s it, there’s nothing more here.

    diff --git a/docs/search.json b/docs/search.json index c22006b..5305ba3 100644 --- a/docs/search.json +++ b/docs/search.json @@ -1 +1 @@ -{"Typealiases.html#/s:6Dwifft34SimpleCollectionViewDiffCalculator":{"name":"SimpleCollectionViewDiffCalculator","abstract":"

    See SimpleTableViewDiffCalculator for explanation

    "},"Typealiases.html#/s:6Dwifft29SimpleTableViewDiffCalculator":{"name":"SimpleTableViewDiffCalculator","abstract":"

    Let’s say your data model consists of different sections containing different model types. Since"},"Structs/SectionedValues.html#/s:FV6Dwifft15SectionedValuescFGSaTxGSaq____GS0_xq__":{"name":"init(_:)","abstract":"

    Initializes the struct with an array of key-pairs.

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:vV6Dwifft15SectionedValues17sectionsAndValuesGSaTxGSaq____":{"name":"sectionsAndValues","abstract":"

    The underlying tuples contained in the receiver

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:FV6Dwifft15SectionedValues9appendingFT15sectionAndValueTxGSaq____GS0_xq__":{"name":"appending(sectionAndValue:)","abstract":"

    Returns a new SectionedValues appending a new key-value pair. I think this might be useful","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:ZFV6Dwifft15SectionedValuesoi2eeFTGS0_xq__GS0_xq___Sb":{"name":"==(_:_:)","abstract":"

    Compares two SectionedValues instances

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:Fe6Dwifft0_Rxs8Hashable_s9EquatablerVS_15SectionedValuescFT6valuesGSaq__14valueToSectionFq_x12sortSectionsFTxx_Sb10sortValuesFTq_q__Sb_GS2_xq__":{"name":"init(values:valueToSection:sortSections:sortValues:)","abstract":"

    This is a convenience initializer of sorts for SectionedValues. It acknowledges","parent_name":"SectionedValues"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft4diffuRxs9EquatablerFTGSax_GSax__GSaGOS_8DiffStepx__":{"name":"diff(_:_:)","abstract":"

    Returns the sequence of DiffSteps required to transform one array into another.

    ","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft5applyurFT4diffGSaGOS_8DiffStepx__7toArrayGSax__GSax_":{"name":"apply(diff:toArray:)","abstract":"

    Applies a diff to an array. The following should always be true:","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft4diffu0_Rxs9Equatable_S1_rFT3lhsGVS_15SectionedValuesxq__3rhsGS2_xq___GSaGOS_17SectionedDiffStepxq___":{"name":"diff(lhs:rhs:)","abstract":"

    Returns the sequence of SectionedDiffSteps required to transform one SectionedValues into another.

    ","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft5applyu0_Rxs9Equatable_S1_rFT4diffGSaGOS_17SectionedDiffStepxq___17toSectionedValuesGVS_15SectionedValuesxq___GS3_xq__":{"name":"apply(diff:toSectionedValues:)","abstract":"

    Applies a diff to a SectionedValues. The following should always be true:","parent_name":"Dwifft"},"Structs/Dwifft.html":{"name":"Dwifft","abstract":"

    Namespace for the diff and apply functions.

    "},"Structs/SectionedValues.html":{"name":"SectionedValues","abstract":"

    SectionedValues represents, well, a bunch of sections and their associated values."},"Extensions/Array.html#/s:Fe6DwifftRxs9EquatablerSa4diffFGSax_GSaGOS_8DiffStepx__":{"name":"diff(_:)","abstract":"

    Deprecated in favor of Dwifft.diff.

    ","parent_name":"Array"},"Extensions/Array.html#/s:Fe6DwifftRxs9EquatablerSa5applyFGSaGOS_8DiffStepx__GSax_":{"name":"apply(_:)","abstract":"

    Deprecated in favor of Dwifft.apply.

    ","parent_name":"Array"},"Extensions/Array.html":{"name":"Array"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep6insertu0_rFMGS0_xq__FTSiSiq__GS0_xq__":{"name":"insert","abstract":"

    An insertion, at a given section and row.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep6deleteu0_rFMGS0_xq__FTSiSiq__GS0_xq__":{"name":"delete","abstract":"

    An deletion, at a given section and row.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep13sectionInsertu0_rFMGS0_xq__FTSix_GS0_xq__":{"name":"sectionInsert","abstract":"

    A section insertion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep13sectionDeleteu0_rFMGS0_xq__FTSix_GS0_xq__":{"name":"sectionDelete","abstract":"

    A section deletion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:vPs28CustomDebugStringConvertible16debugDescriptionSS":{"name":"debugDescription","abstract":"

    A section deletion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/DiffStep.html#/s:FO6Dwifft8DiffStep6inserturFMGS0_x_FTSix_GS0_x_":{"name":"insert","abstract":"

    An insertion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:FO6Dwifft8DiffStep6deleteurFMGS0_x_FTSix_GS0_x_":{"name":"delete","abstract":"

    A deletion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vPs28CustomDebugStringConvertible16debugDescriptionSS":{"name":"debugDescription","abstract":"

    A deletion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vO6Dwifft8DiffStep3idxSi":{"name":"idx","abstract":"

    The index to be inserted or deleted.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vO6Dwifft8DiffStep5valuex":{"name":"value","abstract":"

    The value to be inserted or deleted.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html":{"name":"DiffStep","abstract":"

    These get returned from calls to Dwifft.diff(). They represent insertions or deletions"},"Enums/SectionedDiffStep.html":{"name":"SectionedDiffStep","abstract":"

    These get returned from calls to Dwifft.diff(). They represent insertions or deletions"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator14collectionViewXwGSqCSo16UICollectionView_":{"name":"collectionView","abstract":"

    The collection view to be managed

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator12sectionIndexSi":{"name":"sectionIndex","abstract":"

    All insertion/deletion calls will be made for items at this section.

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator5itemsGSax_":{"name":"items","abstract":"

    Set this variable to automatically trigger the correct item insertion/deletions","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:FC6Dwifft41SingleSectionCollectionViewDiffCalculatorcFT14collectionViewGSqCSo16UICollectionView_12initialItemsGSax_12sectionIndexSi_GS0_x_":{"name":"init(collectionView:initialItems:sectionIndex:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator9tableViewXwGSqCSo11UITableView_":{"name":"tableView","abstract":"

    The table view to be managed

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator12sectionIndexSi":{"name":"sectionIndex","abstract":"

    All insertion/deletion calls will be made on this index.

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator18insertionAnimationOSC23UITableViewRowAnimation":{"name":"insertionAnimation","abstract":"

    You can change insertion/deletion animations like this! Fade works well.","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator4rowsGSax_":{"name":"rows","abstract":"

    Set this variable to automatically trigger the correct row insertion/deletions","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:FC6Dwifft36SingleSectionTableViewDiffCalculatorcFT9tableViewGSqCSo11UITableView_11initialRowsGSax_12sectionIndexSi_GS0_x_":{"name":"init(tableView:initialRows:sectionIndex:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/CollectionViewDiffCalculator.html#/s:vC6Dwifft28CollectionViewDiffCalculator14collectionViewXwGSqCSo16UICollectionView_":{"name":"collectionView","abstract":"

    The collection view to be managed.

    ","parent_name":"CollectionViewDiffCalculator"},"Classes/CollectionViewDiffCalculator.html#/s:FC6Dwifft28CollectionViewDiffCalculatorcFT14collectionViewGSqCSo16UICollectionView_22initialSectionedValuesGVS_15SectionedValuesxq___GS0_xq__":{"name":"init(collectionView:initialSectionedValues:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"CollectionViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:vC6Dwifft23TableViewDiffCalculator9tableViewXwGSqCSo11UITableView_":{"name":"tableView","abstract":"

    The table view to be managed

    ","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:FC6Dwifft23TableViewDiffCalculatorcFT9tableViewGSqCSo11UITableView_22initialSectionedValuesGVS_15SectionedValuesxq___GS0_xq__":{"name":"init(tableView:initialSectionedValues:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:vC6Dwifft23TableViewDiffCalculator18insertionAnimationOSC23UITableViewRowAnimation":{"name":"insertionAnimation","abstract":"

    You can change insertion/deletion animations like this! Fade works well.","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html":{"name":"TableViewDiffCalculator","abstract":"

    This class manages a UITableView’s rows and sections. It will make the necessary calls to"},"Classes/CollectionViewDiffCalculator.html":{"name":"CollectionViewDiffCalculator","abstract":"

    This class manages a UICollectionView’s items and sections. It will make the necessary"},"Classes/SingleSectionTableViewDiffCalculator.html":{"name":"SingleSectionTableViewDiffCalculator","abstract":"

    If your table view only has a single section, or you only want to power a single section of it with Dwifft,"},"Classes/SingleSectionCollectionViewDiffCalculator.html":{"name":"SingleSectionCollectionViewDiffCalculator","abstract":"

    If your collection view only has a single section, or you only want to power a single section of it with Dwifft,"},"Classes.html":{"name":"Classes","abstract":"The following classes are available globally."},"Enums.html":{"name":"Enums","abstract":"The following enums are available globally."},"Extensions.html":{"name":"Extensions","abstract":"The following extensions are available globally."},"Structs.html":{"name":"Structs","abstract":"The following structs are available globally."},"Typealiases.html":{"name":"Typealiases","abstract":"The following typealiases are available globally."}} \ No newline at end of file +{"Typealiases.html#/s:6Dwifft29SimpleTableViewDiffCalculator":{"name":"SimpleTableViewDiffCalculator","abstract":"

    Let’s say your data model consists of different sections containing different model types. Since"},"Typealiases.html#/s:6Dwifft34SimpleCollectionViewDiffCalculator":{"name":"SimpleCollectionViewDiffCalculator","abstract":"

    See SimpleTableViewDiffCalculator for explanation

    "},"Structs/SectionedValues.html#/s:FV6Dwifft15SectionedValuescFGSaTxGSaq____GS0_xq__":{"name":"init(_:)","abstract":"

    Initializes the struct with an array of key-pairs.

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:vV6Dwifft15SectionedValues17sectionsAndValuesGSaTxGSaq____":{"name":"sectionsAndValues","abstract":"

    The underlying tuples contained in the receiver

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:FV6Dwifft15SectionedValues9appendingFT15sectionAndValueTxGSaq____GS0_xq__":{"name":"appending(sectionAndValue:)","abstract":"

    Returns a new SectionedValues appending a new key-value pair. I think this might be useful","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:ZFV6Dwifft15SectionedValuesoi2eeFTGS0_xq__GS0_xq___Sb":{"name":"==(_:_:)","abstract":"

    Compares two SectionedValues instances

    ","parent_name":"SectionedValues"},"Structs/SectionedValues.html#/s:Fe6Dwifft0_Rxs8Hashable_s9EquatablerVS_15SectionedValuescFT6valuesGSaq__14valueToSectionFq_x12sortSectionsFTxx_Sb10sortValuesFTq_q__Sb_GS2_xq__":{"name":"init(values:valueToSection:sortSections:sortValues:)","abstract":"

    This is a convenience initializer of sorts for SectionedValues. It acknowledges","parent_name":"SectionedValues"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft4diffuRxs9EquatablerFTGSax_GSax__GSaGOS_8DiffStepx__":{"name":"diff(_:_:)","abstract":"

    Returns the sequence of DiffSteps required to transform one array into another.

    ","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft5applyurFT4diffGSaGOS_8DiffStepx__7toArrayGSax__GSax_":{"name":"apply(diff:toArray:)","abstract":"

    Applies a diff to an array. The following should always be true:","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft4diffu0_Rxs9Equatable_S1_rFT3lhsGVS_15SectionedValuesxq__3rhsGS2_xq___GSaGOS_17SectionedDiffStepxq___":{"name":"diff(lhs:rhs:)","abstract":"

    Returns the sequence of SectionedDiffSteps required to transform one SectionedValues into another.

    ","parent_name":"Dwifft"},"Structs/Dwifft.html#/s:ZFV6Dwifft6Dwifft5applyu0_Rxs9Equatable_S1_rFT4diffGSaGOS_17SectionedDiffStepxq___17toSectionedValuesGVS_15SectionedValuesxq___GS3_xq__":{"name":"apply(diff:toSectionedValues:)","abstract":"

    Applies a diff to a SectionedValues. The following should always be true:","parent_name":"Dwifft"},"Structs/Dwifft.html":{"name":"Dwifft","abstract":"

    Namespace for the diff and apply functions.

    "},"Structs/SectionedValues.html":{"name":"SectionedValues","abstract":"

    SectionedValues represents, well, a bunch of sections and their associated values."},"Extensions/Array.html#/s:Fe6DwifftRxs9EquatablerSa4diffFGSax_GSaGOS_8DiffStepx__":{"name":"diff(_:)","abstract":"

    Deprecated in favor of Dwifft.diff.

    ","parent_name":"Array"},"Extensions/Array.html#/s:Fe6DwifftRxs9EquatablerSa5applyFGSaGOS_8DiffStepx__GSax_":{"name":"apply(_:)","abstract":"

    Deprecated in favor of Dwifft.apply.

    ","parent_name":"Array"},"Extensions/Array.html":{"name":"Array"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep6insertu0_rFMGS0_xq__FTSiSiq__GS0_xq__":{"name":"insert","abstract":"

    An insertion, at a given section and row.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep6deleteu0_rFMGS0_xq__FTSiSiq__GS0_xq__":{"name":"delete","abstract":"

    An deletion, at a given section and row.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep13sectionInsertu0_rFMGS0_xq__FTSix_GS0_xq__":{"name":"sectionInsert","abstract":"

    A section insertion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:FO6Dwifft17SectionedDiffStep13sectionDeleteu0_rFMGS0_xq__FTSix_GS0_xq__":{"name":"sectionDelete","abstract":"

    A section deletion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/SectionedDiffStep.html#/s:vPs28CustomDebugStringConvertible16debugDescriptionSS":{"name":"debugDescription","abstract":"

    A section deletion, at a given section.

    ","parent_name":"SectionedDiffStep"},"Enums/DiffStep.html#/s:FO6Dwifft8DiffStep6inserturFMGS0_x_FTSix_GS0_x_":{"name":"insert","abstract":"

    An insertion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:FO6Dwifft8DiffStep6deleteurFMGS0_x_FTSix_GS0_x_":{"name":"delete","abstract":"

    A deletion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vPs28CustomDebugStringConvertible16debugDescriptionSS":{"name":"debugDescription","abstract":"

    A deletion.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vO6Dwifft8DiffStep3idxSi":{"name":"idx","abstract":"

    The index to be inserted or deleted.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html#/s:vO6Dwifft8DiffStep5valuex":{"name":"value","abstract":"

    The value to be inserted or deleted.

    ","parent_name":"DiffStep"},"Enums/DiffStep.html":{"name":"DiffStep","abstract":"

    These get returned from calls to Dwifft.diff(). They represent insertions or deletions"},"Enums/SectionedDiffStep.html":{"name":"SectionedDiffStep","abstract":"

    These get returned from calls to Dwifft.diff(). They represent insertions or deletions"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator14collectionViewXwGSqCSo16UICollectionView_":{"name":"collectionView","abstract":"

    The collection view to be managed

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator12sectionIndexSi":{"name":"sectionIndex","abstract":"

    All insertion/deletion calls will be made for items at this section.

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:vC6Dwifft41SingleSectionCollectionViewDiffCalculator5itemsGSax_":{"name":"items","abstract":"

    Set this variable to automatically trigger the correct item insertion/deletions","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionCollectionViewDiffCalculator.html#/s:FC6Dwifft41SingleSectionCollectionViewDiffCalculatorcFT14collectionViewGSqCSo16UICollectionView_12initialItemsGSax_12sectionIndexSi_GS0_x_":{"name":"init(collectionView:initialItems:sectionIndex:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"SingleSectionCollectionViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator9tableViewXwGSqCSo11UITableView_":{"name":"tableView","abstract":"

    The table view to be managed

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator12sectionIndexSi":{"name":"sectionIndex","abstract":"

    All insertion/deletion calls will be made on this index.

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator18insertionAnimationOSC23UITableViewRowAnimation":{"name":"insertionAnimation","abstract":"

    You can change insertion/deletion animations like this! Fade works well.","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:vC6Dwifft36SingleSectionTableViewDiffCalculator4rowsGSax_":{"name":"rows","abstract":"

    Set this variable to automatically trigger the correct row insertion/deletions","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/SingleSectionTableViewDiffCalculator.html#/s:FC6Dwifft36SingleSectionTableViewDiffCalculatorcFT9tableViewGSqCSo11UITableView_11initialRowsGSax_12sectionIndexSi_GS0_x_":{"name":"init(tableView:initialRows:sectionIndex:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"SingleSectionTableViewDiffCalculator"},"Classes/CollectionViewDiffCalculator.html#/s:vC6Dwifft28CollectionViewDiffCalculator14collectionViewXwGSqCSo16UICollectionView_":{"name":"collectionView","abstract":"

    The collection view to be managed.

    ","parent_name":"CollectionViewDiffCalculator"},"Classes/CollectionViewDiffCalculator.html#/s:FC6Dwifft28CollectionViewDiffCalculatorcFT14collectionViewGSqCSo16UICollectionView_22initialSectionedValuesGVS_15SectionedValuesxq___GS0_xq__":{"name":"init(collectionView:initialSectionedValues:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"CollectionViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:vC6Dwifft23TableViewDiffCalculator9tableViewXwGSqCSo11UITableView_":{"name":"tableView","abstract":"

    The table view to be managed

    ","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:FC6Dwifft23TableViewDiffCalculatorcFT9tableViewGSqCSo11UITableView_22initialSectionedValuesGVS_15SectionedValuesxq___GS0_xq__":{"name":"init(tableView:initialSectionedValues:)","abstract":"

    Initializes a new diff calculator.

    ","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html#/s:vC6Dwifft23TableViewDiffCalculator18insertionAnimationOSC23UITableViewRowAnimation":{"name":"insertionAnimation","abstract":"

    You can change insertion/deletion animations like this! Fade works well.","parent_name":"TableViewDiffCalculator"},"Classes/TableViewDiffCalculator.html":{"name":"TableViewDiffCalculator","abstract":"

    This class manages a UITableView’s rows and sections. It will make the necessary calls to"},"Classes/CollectionViewDiffCalculator.html":{"name":"CollectionViewDiffCalculator","abstract":"

    This class manages a UICollectionView’s items and sections. It will make the necessary"},"Classes/SingleSectionTableViewDiffCalculator.html":{"name":"SingleSectionTableViewDiffCalculator","abstract":"

    If your table view only has a single section, or you only want to power a single section of it with Dwifft,"},"Classes/SingleSectionCollectionViewDiffCalculator.html":{"name":"SingleSectionCollectionViewDiffCalculator","abstract":"

    If your collection view only has a single section, or you only want to power a single section of it with Dwifft,"},"Classes.html":{"name":"Classes","abstract":"The following classes are available globally."},"Enums.html":{"name":"Enums","abstract":"The following enums are available globally."},"Extensions.html":{"name":"Extensions","abstract":"The following extensions are available globally."},"Structs.html":{"name":"Structs","abstract":"The following structs are available globally."},"Typealiases.html":{"name":"Typealiases","abstract":"The following typealiases are available globally."}} \ No newline at end of file