Iglistkit: How to use DecorationViews as separators?

Created on 21 Mar 2017  路  4Comments  路  Source: Instagram/IGListKit

New issue checklist

Question

My need is to have a section with multiple cells, some separated by a thin gray line, some not.

Following the discussion in #329 with @rnystrom and @Ricardo1980, I tried to implement separators using the UICollectionViewFlowLayout decoration views (seemed to be it's more appropriate than supplementary views).

However I am still facing the following issue:

separator_layout_issue

When opening the collection view, the decoration views are not correctly positioned. When scrolling, they move to the proper position.

I think that has something to do with the fact I am using self-sizing cells. At opening, the decoration views are displayed where they expect the cell to be, but then the cell is re-sized. When scrolling it obviously triggers a layout event which fixes that. My best guess would to manually trigger this event (layout invalidation?) when cells are displayed, but I don't exactly know when I should trigger what.

The code corresponding to the gif above is available here: https://github.com/Nonepse/ListKitWithDecorators

question

All 4 comments

@jessesquires any tips here?

(1) you probably need to invalidate your layout somewhere before the view appears (that would likely fix this)

(2) this is not really the purpose of decoration views, which are supposed to be purely "decoration". supplementary views carry semantics (e.g., section separation), so I'd recommend using those instead.

I came across a similar issue. For reference, with self-sizing cells, you need to invalidate your decoration elements when invalidateLayout is called in UICollectionViewFlowLayout:

override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) {
    guard let indexPaths = context.invalidatedItemIndexPaths else {
        return
    }
    context.invalidateDecorationElements(ofKind: "your_separator_kind", at: indexPaths)
    super.invalidateLayout(with: context)
}

For the record, we've had a similar issue but we needed to call super if the guard failed, too.

That is:

override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) {
    guard let indexPaths = context.invalidatedItemIndexPaths else {
        super.invalidateLayout(with: context)
        return
    }
    context.invalidateDecorationElements(ofKind: "your_separator_kind", at: indexPaths)
    super.invalidateLayout(with: context)
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

omerfarukyilmaz picture omerfarukyilmaz  路  3Comments

PhilCai1993 picture PhilCai1993  路  3Comments

shuhrat10 picture shuhrat10  路  3Comments

rnystrom picture rnystrom  路  3Comments

kanumuri9593 picture kanumuri9593  路  3Comments