GithubHelp home page GithubHelp logo

sunbohong / iglistkit Goto Github PK

View Code? Open in Web Editor NEW

This project forked from instagram/iglistkit

1.0 2.0 0.0 819 KB

n2one

Home Page: https://github.com/sunbohong/IGListKit

License: Other

Swift 6.76% Ruby 0.29% Objective-C 87.17% Shell 2.38% Objective-C++ 3.40%

iglistkit's Introduction

This is a fork of Instagram/IGListKit .

这个仓库是 Instagram/IGListKit 的一个分支。

Instagram engineering supply a new data-driven UICollectionView framework for building fast and flexible lists.

Instagram engineering 提供了一个数据驱动的 UICollectionView 库,可以快速创建灵活地创建 UICollectionView 视图。

They say IGListKit's main features contain Better architecture with reusable cells and components.

他们声称 更好的架构与可重复使用的单元格和组件 是 IGListKit 的主要特性。

But,I don't think that.

但是,我们还可以更进一步。

In many cases,we only need some similar cells that have some similar subviews but have different layout.

在很多情况下,我们只是需要一些相似的单元格,这些单元格具有一些相似的子视图,但是,它们具有不同的布局。

Just like UITableViewCellStyle.

就像 UITableViewCellStyle。

IGListKit has a limit for this.

IGListKit 对此有很大的限制。

In the same IGListCollectionView view,it only support one UICollectionViewCell class to one IGListSectionController class,and different IGListSectionController can't have the same UICollectionViewCell class.

在同一个IGListCollectionView视图中,UICollectionViewCell类和IGListSectionController类必须一一对应,并且不同的IGListSectionController不能对应同一个UICollectionViewCell类。

For example,https://github.com/Instagram/IGListKit/tree/master/Example create many UICollectionViewCell's subclasss.

例如, https://github.com/Instagram/IGListKit/tree/master/Example 创建了很多UICollectionViewCell的子类。

They may be just a bit different in alignment.

它们之间可能仅仅是对齐有些不同。

I want to avoid this situation.

我希望避免这种情况。

So that,I create n2one.

所以,我创建了 n2one。

In the same IGListCollectionView view,you can use the same UICollectionViewCell class to correspond to different IGListSectionController.

在同一个IGListCollectionView视图中,你可以使用相同的UICollectionViewCell类对应不同的IGListSectionController

Installation

The preferred installation method for IGListKit+n2one is with CocoaPods. Simply add the following to your Podfile:

# Latest release of IGListKit
pod 'IGListKit+n2one'



Build Status Version Status license BSD Platform Carthage compatible


A data-driven UICollectionView framework for building fast and flexible lists.

     | Main Features

---------|--------------- 🙅 | Never call performBatchUpdates(_:, completion:) or reloadData() again 🏠 | Better architecture with reusable cells and components 🔠 | Create collections with multiple data types 🔑 | Decoupled diffing algorithm ✅ | Fully unit tested 🔍 | Customize your diffing behavior for your models 📱 | Simply UICollectionView at its core 🚀 | Extendable API 🐦 | Written in Objective-C with full Swift interop support

IGListKit is built and maintained by Instagram engineering, using the open source version for the Instagram app.

Installation

The preferred installation method for IGListKit is with CocoaPods. Simply add the following to your Podfile:

# Latest release of IGListKit
pod 'IGListKit'

You can also manually install the framework by dragging and dropping the IGListKit.xcodeproj into your workspace.

IGListKit supports a minimum iOS version of 8.0.

Creating your first list

After installing IGListKit, creating a new list is really simple.

Creating a section controller

Creating a new section controller is very simple. You just subclass IGListSectionController and conform to the IGListSectionType protocol. Once you conform to IGListSectionType, the compiler will make sure you implement all of the required methods.

Take a look at LabelSectionController for an example section controller that handles a String and configures a single cell with a UILabel.

class LabelSectionController: IGListSectionController, IGListSectionType {
  // ...
}

Creating the UI

After creating at least one section controller, you must create an IGListCollectionView and IGListAdapter.

let layout = UICollectionViewFlowLayout()
let collectionView = IGListCollectionView(frame: CGRect.zero, collectionViewLayout: layout)

let updater = IGListAdapterUpdater()
let adapter = IGListAdapter(updater: updater, viewController: self, workingRangeSize: 0)
adapter.collectionView = collectionView

Note: This example is done within a UIViewController and uses both a stock UICollectionViewFlowLayout and IGListAdapterUpdater. You can use your own layout and updater if you need advanced features!

Connecting a data source

The last step is the IGListAdapter's data source and returning some data.

func objectsForListAdapter(listAdapter: IGListAdapter) -> [IGListDiffable] {
  // this can be anything!
  return [ "Foo", "Bar", 42, "Biz" ]
}

func listAdapter(listAdapter: IGListAdapter,
    sectionControllerForObject(object: Any) -> IGListSectionController {
  if object is String {
    return LabelSectionController()
  } else {
    return NumberSectionController()
  }
}

func emptyViewForListAdapter(listAdapter: IGListAdapter) -> UIView? {
  return nil
}

You can return an array of any type of data, as long as it conforms to IGListDiffable. We've included a default implementation for all objects, but adding your own implementation can unlock even better diffing.

Diffing

IGListKit uses an algorithm adapted from a paper titled A technique for isolating differences between files by Paul Heckel. This algorithm uses a technique known as the longest common subsequence to find a minimal diff between collections in linear time O(n). It finds all inserts, deletes, updates, and moves between arrays of data.

To add custom, diffable models, you need to conform to the IGListDiffable protocol and implement diffIdentifier() and isEqual(_:).

For an example, consider the following model:

class User {
  let primaryKey: Int
  let name: String
  // implementation, etc
}

The user's primaryKey uniquely identifies user data, and the name is just the value for that user.

Consider the following two users:

let shayne = User(primaryKey: 2, name: "Shayne")
let ann = User(primaryKey: 2, name: "Ann")

Both shayne and ann represent the same unique data because they share the same primaryKey, but they are not equal because their names are different.

To represent this in IGListKit's diffing, add and implement the IGListDiffable protocol:

extension User: IGListDiffable {
  func diffIdentifier() -> NSObjectProtocol {
    return pk
  }

  func isEqual(object: Any?) -> Bool {
    if let object = object as? User {
      return name == object.name
    }
    return false
  }
}

The algorithm will skip updating two User objects that have the same primaryKey and name, even if they are different instances! You now avoid unecessary UI updates in the collection view even when providing new instances.

Note: Remember that isEqual(_:) should return false when you want to reload the cells in the corresponding section controller.

Diffing outside of IGListKit

If you want to use the diffing algorithm outside of IGListAdapter and UICollectionView, you can! The diffing algorithm was built with the flexibility to be used with any models that conform to IGListDiffable.

let result = IGListDiff(oldUsers, newUsers, .equality)

With this you have all of the deletes, reloads, moves, and inserts! There's even a function to generate NSIndexPath results.

Advanced Features

Working Range

A working range is a distance before and after the visible bounds of the UICollectionView where section controllers within this bounds are notified of their entrance and exit. This concept lets your section controllers prepare content before they come on screen (e.g. download images).

The IGListAdapter must be initialized with a range value in order to work. This value is a multiple of the visible height or width, depending on the scroll-direction.

let adapter = IGListAdapter(updater: IGListAdapterUpdater(),
                     viewController: self,
                   workingRangeSize: 0.5) // 0.5x the visible size

working-range

You can set the weak workingRangeDelegate on an section controller to receive events.

Supplementary Views

Adding supplementary views to section controllers is as simple as setting the weak supplementaryViewSource and implementing the IGListSupplementaryViewSource protocol. This protocol works nearly the same as returning and configuring cells.

Display Delegate

Section controllers can set the weak displayDelegate delegate to an object, including self, to receive display events about a section controller and individual cells.

Custom Updaters

The default IGListAdapterUpdater should handle any UICollectionView update that you need. However, if you find the functionality lacking, or want to perform updates in a very specific way, you can create an object that conforms to the IGListUpdatingDelegate protocol and initialize a new IGListAdapter with it.

Check out the updater IGListReloadDataUpdater (used in unit tests) for an example.

Documentation

You can find the docs here. Documentation is generated with jazzy and hosted on GitHub-Pages.

Contributing

Please see the CONTRIBUTING file for how to help out. At Instagram we sync the open source version of IGListKit almost daily, so we're always testing the latest changes. But that requires all changes be thoroughly tested follow our style guide.

License

IGListKit is BSD-licensed. We also provide an additional patent grant.

The files in the /Example directory are licensed under a separate license as specified in each file; documentation is licensed CC-BY-4.0.

iglistkit's People

Contributors

sunbohong avatar sharplet avatar jessesquires avatar marcelofabri avatar

Stargazers

晋先森 avatar

Watchers

James Cloos avatar  avatar

iglistkit's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.