【问题标题】:collectionview with the horizontal scroll with mulitple section具有多个部分的水平滚动的collectionview
【发布时间】:2017-03-02 10:37:02
【问题描述】:

我想像这样开发屏幕(目标 C):

这里有部分名称:

  1. 我们喜爱的新游戏
  2. 我们喜欢的新应用

两者都有水平滚动并且相互独立。

我的问题是我应该使用以下两个选项来实现这一点的可能方式是什么。请提供任何参考样本(如果有):

  1. 我可以使用单个UICollectionView 并具有不同的部分(动态)来实现相同的行为。但是不同部分的滚动应该是独立的。因为第 1 部分可能有不同数量的项目(行),而第 2 部分可能有不同数量的项目(行)
  2. 我是否必须以编程方式获取多个collectionview 然后插入uiscrollview(垂直滚动视图)。 abd 然后定义水平滚动并通过标记 collectionview 在单元格中添加项目。

我目前已经通过以下代码完成了带有水平滚动的collectionview:

- (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);
}

请帮忙。

【问题讨论】:

  • 嘿@ios 开发者。这可能会对您有所帮助:ashfurrow.com/blog/…
  • 我建议你使用storyboards来实现这个。
  • @Adeel 感谢您的评论。我想使用故事板。但是我该如何实现呢?通过采取多个collectionview ?或者一个具有不同部分的集合视图。我需要独立滚动。所以我想我必须采取多个滚动视图。
  • @iosdeveloper 假设您使用 swift 作为编程语言,我已经发布了答案。希望它能解决您的所有顾虑和需求。
  • @check 完整教程代码9to5ios.com/…

标签: ios iphone uicollectionview uicollectionviewcell


【解决方案1】:

你想做的事情并不难。我已经创建了您正在查看的原型。这就是您的storyboard's view controller 及其文档大纲的样子:

这是每个组件的代码

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
}
}

我的CollectionViewCell

class MyCollectionViewCell: UICollectionViewCell {

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

这是模拟器上的样子

【讨论】:

  • 用代码9to5ios.com/…查看完整的objective-c教程
  • 这个答案很有帮助。但是如何在 didSelectItemAtIndexPath 中获得正确的选定项:如果单击了特定的 collectionViewCell。
  • @nOObiOS 你可以使用委托协议。
  • 我在 tableview 中有不同的部分而不是一个部分,每个部分都有 collectionview 单元格。如何在 collectionView 的 cellForItemAtIndexPath 委托中获取 tableview 部分,以根据 tableview 部分填充单元格。
  • @nOObiOS 你可以使用响应者链(nextResponder)。
【解决方案2】:

解决方法(在 Swift 4 中使用 UICollectionView)

我也面临同样的问题,但无法找到使其与 UICollectionViewFlowLayout 一起使用的方法。

如果你想使用UICollectionView,但SupplementaryView不够灵活,你可以这样做:

我在CollectionView 的左上角有一个固定的UILabel 和一个浮动的UILabel,它会相应地向右移动。如果只有一个部分可见,则第二个标签将被隐藏

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

你需要截取section和cell框架来找到最低的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 的解决方案,我将发布其他信息

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    相关资源
    最近更新 更多