菜鸟教程小白 发表于 2022-12-12 14:50:02

ios - UICollectionview 水平和垂直滚动


                                            <p><p>我必须构建一个可水平和垂直滚动的 UICollectionView,我知道网格布局只能沿一个轴水平或垂直滚动​​,所以我阅读了一些帖子并尝试了不同的解决方案,但最简单的是将UIScrollView 中的 UICollectionview。这样,CollectionView 垂直滚动,UIScrollView 水平滚动。
问题是垂直滚动很困难,不流畅,并且经常停止,直到您再次点击并再次拖动。
你能提出一个解决方案吗?谢谢</p>

<pre><code>UICollectionViewFlowLayout *layout = [ init];
UIScrollView *backgroundScroll = [ initWithFrame:CGRectMake(0, 0, .bounds.size.width, .bounds.size.height)];
backgroundScroll.scrollEnabled = YES;   
;
_collectionView = [ initWithFrame:CGRectMake(10, 15, 1020, .bounds.size.height - 35) collectionViewLayout:layout];
;
_collectionView.contentInset = UIEdgeInsetsMake(0, 0, 50, 0);         
_collectionView.scrollEnabled = YES;
</code></pre>

<p>并且我已经实现了方法:</p>

<pre><code>- (void)viewDidLayoutSubviews {
    backgroundScroll.contentSize = self.collectionView.frame.size;
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>这样做的方法是创建一个自定义的 <code>UICollectionViewLayout</code> 子类。</p>

<p>我最近不得不这样做。</p>

<p>让我去拿文件……一秒钟……</p>

<p>首先,您不能轻易地为此使用 <code>UICollectionViewFlowLayout</code> 的子类。流式布局旨在使内容适应一个方向并在另一个方向滚动。这不是你想要的。</p>

<p>创建一个自定义布局来为您做到这一点并不难。</p>

<p><strong>头文件</strong></p>

<pre><code>@interface GridCollectionViewLayout : UICollectionViewLayout

// properties to configure the size and spacing of the grid
@property (nonatomic) CGSize itemSize;
@property (nonatomic) CGFloat itemSpacing;

// this method was used because I was switching between layouts   
- (void)configureCollectionViewForLayout:(UICollectionView *)collectionView;

@end
</code></pre>

<p><strong>实现</strong></p>

<pre><code>#import &#34;GridCollectionViewLayout.h&#34;

@interface GridCollectionViewLayout ()

@property (nonatomic, strong) NSDictionary *layoutInfo;

@end

@implementation GridCollectionViewLayout
</code></pre>

<p>为代码和界面构建器创建初始化...</p>

<pre><code>- (id)init
{
    self = ;
    if (self) {
      ;
    }

    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = ;
    if (self) {
      ;
    }

    return self;
}
</code></pre>

<p>设置默认属性值...</p>

<pre><code>- (void)setup
{
    self.itemSize = CGSizeMake(50.0, 50.0);
    self.itemSpacing = 10.0;
}
</code></pre>

<p>使用它是因为我在不同的布局之间进行更改,但它显示了设置布局所需的内容..</p>

<pre><code>- (void)configureCollectionViewForLayout:(UICollectionView *)collectionView
{
    collectionView.alwaysBounceHorizontal = YES;

    ;
}
</code></pre>

<p>必需的方法。这会迭代项目并为每个项目创建帧 <code>CGRect</code>。将它们保存到字典中。</p>

<pre><code>- (void)prepareLayout
{
    NSMutableDictionary *cellLayoutInfo = ;

    NSInteger sectionCount = ;
    NSIndexPath *indexPath = ;

    for (NSInteger section = 0; section &lt; sectionCount; section++) {
      NSInteger itemCount = ;

      for (NSInteger item = 0; item &lt; itemCount; item++) {
            indexPath = ;

            UICollectionViewLayoutAttributes *itemAttributes =
            ;
            itemAttributes.frame = ;

            cellLayoutInfo = itemAttributes;
      }
    }

    self.layoutInfo = cellLayoutInfo;
}
</code></pre>

<p>这是一种在给定索引处快速获取帧的便捷方法。</p>

<pre><code>- (CGRect)frameForIndexPath:(NSIndexPath *)indexPath
{
    NSInteger column = indexPath.section;
    NSInteger row = indexPath.item;

    CGFloat originX = column * (self.itemSize.width + self.itemSpacing);
    CGFloat originY = row * (self.itemSize.height + self.itemSpacing);

    return CGRectMake(originX, originY, self.itemSize.width, self.itemSize.height);
}
</code></pre>

<p>计算内容大小所需的方法。这只是将部分或项目的数量乘以大小和间距属性。这是允许双向滚动的原因,因为内容大小可以大于 Collection View 的宽度和高度。</p>

<pre><code>- (CGSize)collectionViewContentSize
{
    NSInteger sectionCount = ;

    if (sectionCount == 0) {
      return CGSizeZero;
    }

    NSInteger itemCount = ;

    CGFloat width = (self.itemSize.width + self.itemSpacing) * sectionCount - self.itemSpacing;
    CGFloat height = (self.itemSize.height + self.itemSpacing) * itemCount - self.itemSpacing;

    return CGSizeMake(width, height);
}
</code></pre>

<p>必需的方法。这些告诉 Collection View 每个项目需要放置在哪里。</p>

<pre><code>- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return self.layoutInfo;
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *allAttributes = ;

    [self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath, UICollectionViewLayoutAttributes *attributes, BOOL *stop) {
      if (CGRectIntersectsRect(attributes.frame, rect)) {
            ;
      }
    }];

    return allAttributes;
}

@end
</code></pre>

<p>当然,这种情况下的布局是针对我个人问题的。</p>

<p>布局的工作方式是让每个部分都是一列,每个部分中的项目都是行。所以像这样......</p>

<pre><code>xy = item y in section x

00 10 20 30 ...
01 11 21 31 ...
02 12 22 32 ...
....
....
....
</code></pre>

<p>显然,可以有无限数量的部分或部分中的项目,因此我必须双向滚动。</p>

<p>一旦你创建了你的布局类,你只需要将它设置为你的 Collection View 的布局。您可以在代码 <code>collectionView.collectionViewLayout = myLayout</code> 中执行此操作,也可以在 Interface Builder 中使用 Collection View 上的“layout”属性执行此操作。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - UICollectionview 水平和垂直滚动,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/29302772/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/29302772/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - UICollectionview 水平和垂直滚动