带有多个部分

时间:2016-10-20 12:18:10

标签: ios iphone uicollectionview uicollectionviewcell

我想像这样开发屏幕(目标C):enter image description here

在这里有部分名称:

  1. 我们喜爱的新游戏
  2. 我们喜欢的新应用
  3. 两者都有水平滚动并且彼此独立。

    我的问题是我应该用什么方法来实现以下两个选项。如果有的话,请提供任何参考样本:

    1. 我可以使用单个UICollectionView和不同的部分(动态)实现相同的行为。但不同部分的滚动应该是独立的。因为第1部分可能有不同数量的项目(行),第2部分可能有不同数量的项目(行)
    2. 我是否必须以编程方式获取多个collectionview 然后插入uiscrollview(垂直scrollview)。 abd然后定义水平滚动并通过分类集合视图添加单元格中的项目。
    3. 我目前使用下面的代码完成了水平滚动的集合视图:

      - (void)viewDidLoad {
          [super viewDidLoad];
      
          self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
      
          UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
          _collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
          [_collectionView setDataSource:self];
          [_collectionView setDelegate:self];
      
          [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
          [_collectionView setBackgroundColor:[UIColor redColor]];
      
          [self.view addSubview:_collectionView];
      
          // Do any additional setup after loading the view, typically from a nib.
      }
      
      #pragma mark Collection View Methods
      
      - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
      {
          return 15;
      }
      
      // The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
      - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
      {
          UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];
      
          cell.backgroundColor=[UIColor greenColor];
          return cell;
      }
      
      - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
      {
          return CGSizeMake(50, 50);
      }
      

      请帮忙。

2 个答案:

答案 0 :(得分:16)

你要做的并不是那么困难。我已经创建了你所看到的原型。这就是您的storyboard's view controller及其文档大纲的样子:

Storyboard

以下是每个组件的代码

TableViewController

class TableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 5
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! MyTableViewCell

    return cell
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 160
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return (section%2 == 0) ? "Games we love" : "Apps we love"
}
}

MyTableViewCell

class MyTableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

@IBOutlet weak var collectionView: UICollectionView!

let imageNames = ["candy_crush", "cut_the_ropes", "game_1", "little_pet_shop", "zuba"]
let gameNames  = ["Candy Crush", "Cut the Ropes", "Arbitrary Game 1", "Littlest Pet Shop", "Zuba"]

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return imageNames.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as! MyCollectionViewCell
    cell.imageView.image  = UIImage.init(named: imageNames[indexPath.row])
    cell.titleLabel.text  = gameNames[indexPath.row]
    cell.detailLabel.text = "Games"

    return cell
}
}

MyCollectionViewCell

class MyCollectionViewCell: UICollectionViewCell {

@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var detailLabel: UILabel!
}

这就是它在模拟器上的样子

enter image description here

答案 1 :(得分:0)

解决方法(使用UICollectionView和Swift 4)

我遇到了同样的问题,无法找到使其与UICollectionViewFlowLayout一起使用的方法。

如果您想使用UICollectionView,但SupplementaryView不够灵活,您可以执行此解决方法:

UILabel的左上角有一个固定的CollectionView,另一个浮动的UILabel会相应地移动到右边。如果只有一个部分可见,则隐藏第二个标签

我们可以拦截collectionView:cellForItemAt indexPath:方法中正在创建/出列的所有单元格,但会给你很多单元格框架(其中许多正在准备但仍在屏幕外,你必须管理哪些框架对应如果在水平滚动集合视图中有多行,这可能会很棘手

您需要拦截部分和单元格框架以找到最低的x坐标,最可靠的方法是检查collectionView的.visibleCells属性。这可能是很多迭代(取决于可见细胞的数量),我喜欢识别更有效的方法。 (委托方法,CollectionViewCellsDidAppear类型的通知,或者能够将Observer添加到.visibleCells属性(不可能,因为它是只读的)

到目前为止,这有效(Swift 4),但还有改进的余地:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CellID", for: indexPath) as! GalleryCell
    cell.label?.text = String((itemsArrays[indexPath.section][indexPath.row]))
    var pointsDict = Dictionary<Int, CGFloat>()
    for item in collectionView.visibleCells {
        let point = item.convert(CGPoint.zero, to: self.superview)
        let section = collectionView.indexPath(for: item)!.section
        if pointsDict[section] != nil {
            if point.x < pointsDict[section]! {
                pointsDict[section] = point.x
            }
        } else {
            pointsDict[section] = point.x
        }
    }
    updateLabels(dict: pointsDict)
    return cell
}

此代码将为您提供一个包含可见部分(键)的字典和每个部分(值)的最低x坐标,以对齐浮动label2(我的label1在collectionView的左侧有一个固定的x)。您还可以相应地设置,隐藏/显示标签

此解决方法并非最佳,如果使用UICollectionViewFlowLayout

的解决方案,我会发布其他信息