collectionViewLayout sizeForItemAtIndexPath -> CGSize 奇怪的行为

collectionViewLayout sizeForItemAtIndexPath -> CGSize Strange behaviour

所以有趣的是我正在尝试使用 collectionViewLayout sizeForItemAtIndexPathcollectionView 中一次只显示一个项目并水平滚动,我试过这个:

- (void)viewDidLoad {
    [super viewDidLoad];

    flowLayout = [[UICollectionViewFlowLayout alloc]init];
    
    flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    flowLayout.minimumInteritemSpacing = 0.0;
    
    flowLayout.minimumLineSpacing = 0.0;
    
    _obj_CollectionView.pagingEnabled = YES;
    _obj_CollectionView.collectionViewLayout = flowLayout;
    
    self.obj_CollectionView.delegate = self;
    self.obj_CollectionView.dataSource = self;
    _obj_CollectionView.backgroundColor = [UIColor redColor];
}


-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(collectionView.frame.size.width, collectionView.frame.size.height);
}

这是 collectionView 截图:

这里紫色是我的单元格,红色是我的 collectionView 但我想要整个紫色。

所以请指导我。我很困惑。 :)

我做了一些概念验证,它按我的预期工作。 也许您的 CollectionViewCell 有问题(错误/缺少约束)?

import UIKit


class CollectionViewController: UICollectionViewController {
    let layout = UICollectionViewFlowLayout()

    override func viewDidLoad() {
        super.viewDidLoad()

        layout.scrollDirection = .horizontal
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0

        collectionView?.collectionViewLayout = layout
        collectionView?.isPagingEnabled = true
    }


    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }


    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
        cell.backgroundColor = (indexPath.item % 2 == 0) ? UIColor.purple : UIColor.blue

        return cell
    }
}

extension CollectionViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return self.view.frame.size
    }
}

首先,您不需要以编程方式创建 UICollectionViewFlowLayout 的对象。也不需要viewDidLoad()中编写的代码。您可以使用 storyboarddelegate 方法完成所有这些操作。

下面是您的问题的代码:

import UIKit

class ViewController: UIViewController
{
    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad()
    {
        super.viewDidLoad()
    }
}

extension ViewController : UICollectionViewDataSource
{
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        return 10
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
        cell.backgroundColor = (indexPath.item % 2 == 0) ? UIColor.purple : UIColor.blue
        return cell
    }
}

extension ViewController : UICollectionViewDelegateFlowLayout
{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
    {
        return CGSize(width: collectionView.bounds.width, height: collectionView.bounds.height)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
    {
        return 0
    }

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
    {
        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }
}

故事板截图:

输出画面:

你有一些调试选项来检查这是什么原因:

  • NSLog() 框架 UICollectionView
  • NSLog() CGSize 检查返回的实际大小
  • 尝试设置硬编码大小来检查行为。
  • 如果使用 autoLayout,请在移除约束后尝试。

希望这会有所帮助。

好的,我明白了。 让我先 post 我的故事板的布局。

我采用了 iPhone6 布局并对集合视图进行了以下约束

设置布局

  1. 将集合视图的宽度固定为视图的宽度

  2. 接下来我修复了collection view的纵横比,让它永远是正方形

  1. 最后我们添加了顶部、尾部和前导约束。

现在,我将布局从垂直更改为水平滚动,并添加了以下代码。

代码实现

 #import "ViewController.h"

 @interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>

 @property (nonatomic,weak) IBOutlet UICollectionView *clcnView;

 @end

 @implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

#pragma mark - Collection View methods- 

 -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
     static NSString *reuse = @"cell";
     UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuse forIndexPath:indexPath];
     cell.backgroundColor = randomColor();
     return cell;
 }


-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
     return 10;
 }


 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

     CGFloat fl = self.clcnView.frame.size.width;
     CGSize mElementSize = CGSizeMake(fl-1, fl-1);
     return mElementSize;
 }
 - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
     return 1.0;
 }

   - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout  minimumLineSpacingForSectionAtIndex:(NSInteger)section {
     return 1.0;
 }

  - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
     return UIEdgeInsetsMake(0,0,0,0);
 }


 UIColor * randomColor(){
     return [UIColor colorWithRed:arc4random_uniform(255)/255.0f green:arc4random_uniform(255)/255.0f blue:arc4random_uniform(255)/255.0f alpha:1.0];
 }


 @end

成功了。 以下是截图

在IPhone

在iPad

希望这能解决您的问题。

请试试这个,它会对你有所帮助。

#pragma mark -- Collection View Delegate and datasource method --
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return 10;
}


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *identifier = @"Cell";


    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

    UILabel *title = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, cell.bounds.size.width - 40, 22)];
    title.tag = 200;
    title.backgroundColor = [UIColor purpleColor];
    [cell.contentView addSubview:title];

    return cell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView
                  layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    CGFloat width = self.collectionViewSearchCity.frame.size.width/2-20;
    return CGSizeMake(width, 50.0);
}



- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
    return UIEdgeInsetsMake(0, 15, 0,15);
}

试试这个:

func collectionView(collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                           minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 1.0
}

func collectionView(collectionView: UICollectionView, layout
    collectionViewLayout: UICollectionViewLayout,
    minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 1.0
}

ViewDidload:

layout.minimumInteritemSpacing = 20
layout.minimumLineSpacing = 10

CellforrowAtIndexPath:

cell.image.clipsToBounds = true
cell.contentView.frame = cell.bounds