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

Создайте книжную полку с помощью UICollectionView

Я собираюсь создать книжную полку в одном из моих проектов. Основное требование заключается в следующем:

  • похож на книжную полку iBooks
  • хорошо поддерживает обе ориентации
  • хорошо поддерживает все виды устройств iOS (разные разрешения)
  • поддерживает удаление и вставку элементов
  • поддерживает переупорядочение элементов длинным нажатием
  • показывает скрытый логотип, когда первый ряд опущен

UICollectionView - первая опция, которая пришла мне в голову. Он легко поддерживает ячейки сетки. Я нашел его в Google и нашел несколько очень полезных уроков:

Брайан Хансен UICollectionПросмотр учебника по пользовательскому макету

Mark Pospesel Как добавить декоративный вид в UICollectionView

LXReorderableCollectionViewFlowLayout

И вот результат: (Пожалуйста, не обращайте внимания на проблему несоответствия цвета, поскольку выбранная графика еще не идеальна.)

enter image description here

Что я сделал:

  1. Создал пользовательский макет, создав класс, унаследованный от LXReorderableCollectionViewFlowLayout (для целей переупорядочения), который унаследован от UICollectionFlowLayout
  2. Добавлен вид оформления для отображения логотипа
  3. Добавлен вид оформления для отображения книжных полок

Но я столкнулся с несколькими проблемами:

1. Я не могу прокручивать вообще, если элементы могут быть показаны на одном экране

Затем я добавил следующий код, чтобы увеличить размер содержимого

- (CGSize)collectionViewContentSize
{
    return CGSizeMake(self.collectionView.bounds.size.width,      self.collectionView.bounds.size.height+100);
}

Тогда я могу прокрутить сейчас. Здесь я опускаю первый ряд:

enter image description here

Вы можете увидеть, как работает декоративный вид логотипа.

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

enter image description here

Вы можете видеть, что декоративный вид не добавлен в зеленой части окна.

3. Фон оформления для книжной полки становится все темнее и темнее. (Пожалуйста, обратитесь к той же проблеме здесь

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

enter image description here

Я перечислю некоторые важные коды здесь:

- (void)prepareLayout
{
    // call super so flow layout can do all the math for cells, headers, and footers
    [super prepareLayout];

    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    NSMutableDictionary *shelfLayoutInfo = [NSMutableDictionary dictionary];

    // decoration view - emblem
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
    UICollectionViewLayoutAttributes *emblemAttributes =
        [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:[EmblemView kind]
            withIndexPath:indexPath];
    emblemAttributes.frame = [self frameForEmblem:YES];
    dictionary[[EmblemView kind]] = @{indexPath: emblemAttributes};

    // Calculate where shelves go in a vertical layout
    int sectionCount = [self.collectionView numberOfSections];

    CGFloat y = 0;
    CGFloat availableWidth = self.collectionViewContentSize.width - (self.sectionInset.left + self.sectionInset.right);
    int itemsAcross = floorf((availableWidth + self.minimumInteritemSpacing) / (self.itemSize.width + self.minimumInteritemSpacing));

    for (int section = 0; section < sectionCount; section++)
    {
        y += self.headerReferenceSize.height;
        //y += self.sectionInset.top;

        int itemCount = [self.collectionView numberOfItemsInSection:section];
        int rows = ceilf(itemCount/(float)itemsAcross)+1; // add 2 more empty row which does not have any data
        for (int row = 0; row < rows; row++)
        {
            indexPath = [NSIndexPath indexPathForItem:row inSection:section];
            shelfLayoutInfo[indexPath] = [NSValue valueWithCGRect:CGRectMake(0,y, self.collectionViewContentSize.width, self.itemSize.height + DECORATION_HEIGHT)];
            y += self.itemSize.height;

            if (row < rows - 1)
                y += self.minimumLineSpacing;
        }

        y += self.sectionInset.bottom;
        y += self.footerReferenceSize.height;
    }

    dictionary[[ShelfView kind]] = shelfLayoutInfo;

    self.shelfLayoutInfo = dictionary;
}


- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray *attributesArrayInRect = [super layoutAttributesForElementsInRect:rect];

    // cell layout info
    for (BookShelfLayoutAttributes *attribs in attributesArrayInRect)
    {

        attribs.zIndex = 1;
        CATransform3D t = CATransform3DIdentity;
        t = CATransform3DTranslate(t, 0, 0, 40);
        attribs.transform3D = CATransform3DRotate(t, 15 * M_PI / 180, 1, 0, 0);
    }

    // Add our decoration views (shelves)
    NSMutableDictionary* shelfDictionary = self.shelfLayoutInfo[[ShelfView kind]];
    NSMutableArray *newArray = [attributesArrayInRect mutableCopy];

    [shelfDictionary enumerateKeysAndObjectsUsingBlock:^(id key, NSValue* obj, BOOL *stop) {

        if (CGRectIntersectsRect([obj CGRectValue], rect))
        {
            UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:[ShelfView kind] withIndexPath:key];
            attributes.frame = [obj CGRectValue];

            NSLog(@"decorationView rect = %@",NSStringFromCGRect(attributes.frame));
            attributes.zIndex = 0;
            //attributes.alpha = 0.5; // screenshots
            [newArray addObject:attributes];
        }
    }];

    attributesArrayInRect = [NSArray arrayWithArray:newArray];

    NSMutableDictionary* emblemDictionary = self.shelfLayoutInfo[[EmblemView kind]];
    NSMutableArray *newArray2 = [attributesArrayInRect mutableCopy];
    [emblemDictionary enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath, UICollectionViewLayoutAttributes *attributes, BOOL *innerStop) {
        if (CGRectIntersectsRect(rect, attributes.frame)) {
            [newArray2 addObject:attributes];
        }
    }];

    attributesArrayInRect = [NSArray arrayWithArray:newArray2];

    return attributesArrayInRect;
}

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

4b9b3361

Ответ 1

Я бы посоветовал проверить вашу последнюю строку и сделать [self.collectionView ScrollEnable:NO] то же самое для первой строки, установить цвет фона, очищенный от collectionView и collectionViewCell, и что изображение книжной полки устанавливается на фоне фона.