UICollectionView сохраняет горизонтальную позицию прокрутки списка - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть некоторые горизонтальные UICollectionViewCell в моем UICollectionView.

Моя проблема в том, что если я прокручиваю horizontal list в первой ячейке в другую позицию, четвертая ячейка также будет в той же позиции.

То же самое для второго и пятого, третьего и шестого ...

Также не переводите keep horizontal scroll position из портрета в пейзаж или наоборот.

Есть ли способ для UICollectionView в клетках сохранить свою позицию?

Обновление 2:

Я знаю, что должен сохранить внутреннее horizontal представление коллекции content offsets в массиве. Я читал об этом в ссылке ниже, но в ссылке ниже они хотят добиться этого в UITableView и UIScrollView. И я хочу добиться этого в UICollectionView внутри UICollectionViewController.

Вид прокрутки в UITableViewCell не сохранит позицию

Обновлено 1:

https://imgur.com/a/F8EGsTx

ViewController.swift

import UIKit

class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    let cellId = "cellId"

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView?.backgroundColor = .white
        collectionView?.register(CategoryCell.self, forCellWithReuseIdentifier: cellId)
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CategoryCell
        cell.nameLabel.text = "Horizontal list #\(indexPath.item)"
        return cell
    }

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

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: 150)
    }

}

CategoryCell.swift

import UIKit

class CategoryCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    let cellId = "categoryId"

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    var nameLabel: UILabel = {
        let label = UILabel()
        label.text = "Horizontal list #1"
        label.font = UIFont.systemFont(ofSize: 16)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    let appsCollectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.backgroundColor = .white
        return collectionView
    }()

    let dividerLineView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(white: 0.4, alpha: 0.4)
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    func setupViews() {

        addSubview(appsCollectionView)
        addSubview(dividerLineView)
        addSubview(nameLabel)

        appsCollectionView.dataSource = self
        appsCollectionView.delegate = self

        appsCollectionView.register(AppCell.self, forCellWithReuseIdentifier: cellId)

        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-14-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel]))

        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-14-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": dividerLineView]))

        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": appsCollectionView]))

        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[nameLabel(30)][v0][v1(0.5)]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": appsCollectionView, "v1": dividerLineView, "nameLabel": nameLabel]))

    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! AppCell
        cell.imageView.backgroundColor = UIColor(hue: CGFloat(indexPath.item) / 20.0, saturation: 0.8, brightness: 0.9, alpha: 1)
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 100, height: frame.height - 32)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsetsMake(0, 14, 0, 14)
    }

}

AppCell.swift

import UIKit

class AppCell: UICollectionViewCell {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    let imageView: UIImageView = {
        let iv = UIImageView()
        iv.contentMode = .scaleAspectFill
        iv.layer.cornerRadius = 16
        iv.layer.masksToBounds = true
        return iv
    }()

    func setupViews() {
        addSubview(imageView)

        imageView.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.width)
    }
}

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Я наконец-то понял:)

Благодаря 3-летнему проекту! от ирфанлоне

https://github.com/irfanlone/Collection-View-in-a-collection-view-cell

Он работает и поддерживает ориентацию интерфейса, но требует некоторой оптимизации.

Например, если прокрутить вправо, а затем быстро прокрутить вниз, а затем прокрутить назад до верхней части ячейки, у нее будет дополнительное поле от правого края! Также есть некоторые проблемы с ориентацией интерфейса.

Если у кого-нибудь есть полная версия, поделитесь этим, спасибо.

Для всех, кому это может быть интересно, добавьте следующий код в указанные файлы.

ViewController.swift

var storedOffsets = [Int: CGFloat]()

override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    guard let collectionViewCell = cell as? CategoryCell else { return }
    collectionViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
}

override func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    guard let collectionViewCell = cell as? CategoryCell else { return }
    storedOffsets[indexPath.row] = collectionViewCell.collectionViewOffset
}

CategoryCell.swift

var collectionViewOffset: CGFloat {
    set {
        appsCollectionView.contentOffset.x = newValue
    }

    get {
        return appsCollectionView.contentOffset.x
    }
}
0 голосов
/ 03 сентября 2018

Внутренние представления коллекции используются повторно. Если вы хотите сохранить положение прокрутки для каждого горизонтального представления коллекции, вы должны сохранить массив позиций прокрутки в вашем UIViewController и обновить его, когда прокручивается представление внутреннего сбора. Затем при повторном использовании ячеек внешнего вида коллекции вы можете сбросить позицию прокрутки в методе collectionView(collectionView:, cellForItemAt indexPath:).

Ваш метод заполнения внешнего вида коллекции должен выглядеть примерно так:

 override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
          let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CategoryCell
          cell.nameLabel.text = "Horizontal list #\(indexPath.item)"
          cell.scrollPosition = this.scrollPositions[indexPath.item]
          return cell
}
...