2013-04-06 19 views
24

Tôi sẽ tạo giá sách trong một trong các dự án của mình. Yêu cầu cơ bản là như sau:Tạo giá sách bằng cách sử dụng UICollectionView

  • tương tự như iBooks kệ sách
  • hỗ trợ cả định hướng tốt
  • hỗ trợ tất cả các loại thiết bị iOS tốt (độ phân giải khác nhau)
  • hỗ trợ xóa và chèn mục
  • hỗ trợ sắp xếp lại các mục theo cử chỉ báo chí dài
  • hiển thị biểu tượng ẩn khi hàng đầu tiên bị kéo xuống

UICollectionView là tùy chọn đầu tiên xảy ra với tôi. Nó dễ dàng hỗ trợ các ô lưới. Vì vậy, tôi googled nó và tìm thấy một số hướng dẫn rất hữu ích:

Bryan Hansen's UICollectionView custom layout tutorial

Mark Pospesel's How to Add a Decoration View to a UICollectionView

LXReorderableCollectionViewFlowLayout

Và đây là kết quả: (Vui lòng bỏ qua vấn đề màu mâu thuẫn vì đồ họa tôi đã chọn là chưa hoàn hảo.)

enter image description here

Những gì tôi đã làm:

  1. Tạo một bố cục tùy chỉnh bằng cách tạo ra một lớp kế thừa từ LXReorderableCollectionViewFlowLayout (đối với sắp xếp lại các mục đích) mà thừa hưởng từ UICollectionFlowLayout
  2. gia tăng một cái nhìn trang trí cho hiển thị biểu tượng
  3. gia tăng một cái nhìn trang trí cho hiển thị các bookshelfs

Nhưng tôi chạy vào một vài vấn đề:

1. Tôi không thể di chuyển ở tất cả nếu các mục có thể được hiển thị trong một màn hình

Sau đó, tôi thêm vào đoạn mã sau, để làm cho contentsize lớn

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

Sau đó, tôi có thể di chuyển ngay bây giờ. Ở đây tôi kéo xuống dòng đầu tiên:

enter image description here

Bạn có thể thấy quan điểm trang trí cho biểu tượng đang làm việc.

2. Nhưng tôi đã tập thứ hai của vấn đề khi tôi kéo lên hàng cuối cùng:

enter image description here

Bạn có thể thấy quan điểm trang trí không được thêm vào ở phần hộp màu xanh lá cây.

3.Các nền của trang trí xem cho kệ sách là nhận được tối hơn và tối hơn. (Vui lòng tham khảo same problem here

4. Thanh kệ sách đôi khi di chuyển khi tôi sắp xếp lại các mục

enter image description here

tôi liệt kê một số các mã quan trọng ở đây:

- (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 doesn't 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; 
} 

Tôi sẽ đánh giá cao nếu bạn đủ kiên nhẫn để đọc bài đăng này và cung cấp bất kỳ lời khuyên hoặc đề xuất nào. Tôi sẽ đăng mã nguồn hoàn chỉnh nếu tôi có thể sửa tất cả các vấn đề. Cảm ơn bạn trước.

+0

Tôi đã tìm thấy bài đăng trong diễn đàn của Apple. Có vẻ như sự trùng lặp của DecorationView là một lỗi. https://devforums.apple.com/message/773776#773776 –

+0

Bạn thực sự nên tính kích thước nội dung của chế độ xem bộ sưu tập như một phần của hàm prepareLayout của bạn. Khi nó đứng, bất kể có bao nhiêu mục trong giao diện bộ sưu tập, bạn sẽ chỉ có thể cuộn xuống 100 pixel. – Ash

Trả lời

0

Tôi khuyên bạn nên kiểm tra hàng cuối cùng của mình và thực hiện [self.collectionView ScrollEnable: NO] giống với hàng đầu tiên, đặt màu nền rõ ràng là collectionView và collectionViewCell và hình ảnh giá sách đó đặt ở chế độ xem nền.

Các vấn đề liên quan