Подтвердить что ты не робот

UICollectionView Decoration и дополнительные представления не могут быть перемещены

В UICollectionView украшение и дополнительные взгляды кажутся большой загадкой. На данный момент, похоже, нет кода примера. Мне удалось заставить оба типа работать в настраиваемом макете (см. Этот пост для некоторых деталей). Пока они остаются в одном и том же положении, все нормально (т.е. Если их layoutAttributes.frame не изменяется).

Однако, как только я переформатирую с измененным layoutAttributes для украшения или дополнительных видов, они визуально дублируются - т.е. есть копия в фоновом режиме в исходном месте и копия на новом месте. Поведение идентично, если я создаю их из XIB или полностью в коде, и поведение не происходит для нормальных ячеек.

Сначала я подумал, что это какая-то проблема с перерисованием, но эти "копии" выживают при повторной компоновке, перерисовке и т.д. Однако они не являются настоящими копиями, так как layoutAttributesForDecorationView и т.д. никогда не вызываются для них (только для новых мест). Кажется, что кеширование в фоновом режиме в UICollectionView.

Кто-нибудь получил эту работу или идеи. Я должен сказать, что я новичок в платформе iOS, так что это могут быть простые вещи, такие как настройка свойств "Clips Bound" или "Clear Graphics Context" (я пробовал их, но это могло быть что-то подобное).

Это сводит меня с ума, и странно, что нет абсолютно никакого кода примера.

Я спрашиваю себя: не украшены ли украшения и дополнительные взгляды? (Надеюсь, нет)

4b9b3361

Ответ 1

Привет, это старый вопрос, но для него есть ответ.

На самом деле у меня были и эти проблемы, когда я реализовал свой собственный объект Layout, пока не понял, что необходимо кэшировать любые объекты атрибутов макета, которые вы создаете в своем настраиваемом макете. В документации есть очень неопределенная ссылка на это (я не могу вспомнить точное местоположение сейчас), что очень легко неверно истолковано.

По сути, как только вы запросили объект layoutAttributes для ячейки по пути указателя, вы должны сохранить объект атрибутов (например, сохранить его в словаре с указательным путем в качестве ключа) и вернуть тот же объект атрибутов для любого и все последующие запросы для атрибутов. Если вы этого не сделаете, но вместо этого создадите новые атрибуты макета, анимация пакетных обновлений приведет к серьезным графическим сбоям и артефактам.

Ответ 2

У меня была такая же проблема. кажется, что есть некоторые ошибки с UICOllectionview (это не первое, что я видел). Я исправил его, не используя "performBatchUpdates". Я теряю анимацию, но в списке нет нежелательного представления.

Ответ 3

Я думаю, что Apple покажет, по крайней мере, в случае взглядов на декорирование, что они работают по назначению. Я столкнулся с той же проблемой, что и в предыдущем разделе, и попытался настроить представление "Украшение", чтобы окружить разделы по мере их изменения. Используя простой вид, который сначала имел красный фон, весь фон моего приложения стал красным, и это меня смутило. Впоследствии я изменил альфа-значение на 0.3f на атрибуты компоновки видов оформления, и я смог увидеть их слой друг на друга по мере изменения разделов.

Что действительно подсказывало мне, что это может быть по дизайну, хотя это была строка, которую я читал в учебнике по UICollectionView

С другой стороны, декоративные виды являются "декоративными", а не data-driven: подумайте о книжной полке в приложении iBooks.

Ключ состоит в том, что декорации не управляются данными и не должны меняться по мере изменения ваших данных независимо от того, сможете ли вы сделать это в пользовательском макете. Как и в случае с книжной полкой, размер полок не меняется после их создания.

Ответ 4

Я знаю, что это старый вопрос, но я натолкнулся на это, когда проблемы с дополнительными представлениями дублируются повсюду, когда они недействительны. Я считаю, что это ошибка, и я исправил ее с помощью ove-riding invalidateLayout в моем объекте макета и удалив дополнительные представления, как показано ниже:

- (void)invalidateLayout {
    [super invalidateLayout];
    // Manually remove all suplementary views of a certain type
    /**
     ** This appears to be a BUG. Invalidate view does not remove suplementary view
     **     from the view hierachy. But they are Orphaned so stay on screen. 
     **/
    for (UIView *subview in [self.collectionView subviews]) {
        if ([subview isKindOfClass:[UICollectionReusableView class]]) {
            [subview removeFromSuperview];
        }
    }
}

Замените UICollectionReusableView классом вашего повторно используемого вида, которое остается на экране.

Надеюсь, это поможет кому-то.

Ответ 5

У меня был подобный симптом. Моя проблема заключалась в том, что я случайно включил дополнительное представление reuseID вместо kindID при создании моего настраиваемого макета.

В частности, у меня было это (Неверно)

UICollectionViewLayoutAttributes *attributes = 
  [UICollectionViewLayoutAttributes
    layoutAttributesForSupplementaryViewOfKind:myViewReuseID
    withIndexPath:sectionIndexPath];

Когда мне нужно это (Вправо)

UICollectionViewLayoutAttributes *attributes = 
  [UICollectionViewLayoutAttributes
    layoutAttributesForSupplementaryViewOfKind:myViewKindID
    withIndexPath:sectionIndexPath];

Это означало, что prepareForReuse никогда не вызывали, и мои старые взгляды никогда не исчезали. Вместо этого они продолжали накапливаться.