Несколько UICollectionView в UITableView переплетаются при прокрутке

Я совершенно новичок в разработке iOS, поэтому моя проблема может быть нубским вопросом, но я понятия не имею, как сделать мою UICollectionViews прокрутку отдельно друг от друга. Когда я прокручиваю свой верхний UICollectionView, прокручиваю вниз, мой другой UICollectionView также прокручивается, не касаясь его.

UICollectionView настроен на горизонтальную прокрутку. Я хочу добиться чего-то вроде того, что сделал Netflix. Пользователь может прокручивать по горизонтали, а список элементов отображается горизонтально. Пока все работает, за исключением того, что прокрутка одного списка заставляет прокручиваться и другие, когда они перерисовываются (я думаю, поскольку я вижу, что это происходит только в списках, которые еще не отображаются на устройстве).

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

Итак, мой UITableController выглядит так:

class MoviesViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var containerView: UIView!
@IBOutlet weak var tableView: UITableView!

let categories = ["In theaters", "Popular", "Upcoming", "Top rated"]

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    containerView.backgroundColor = UIColor.init(hex: "232637")
    tableView.backgroundColor = UIColor.init(hex: "232637")
}

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

func numberOfSections(in tableView: UITableView) -> Int {
    return categories.count
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    tableView.rowHeight = 332;
    let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! TableViewCell
    return cell
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 42;
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return categories[section]
}

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){
    view.tintColor = UIColor.init(hex: "232637")
    let header = view as! UITableViewHeaderFooterView
    header.textLabel?.textColor = UIColor.init(hex: "ff5959")
}

}

мой UITableViewCell выглядит так:

class TableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

@IBOutlet weak var collectionView: UICollectionView!

let imageNames = //Some filler data
let gameNames  = //Some filler data

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
    collectionView.backgroundColor = UIColor.init(hex: "232637")
    collectionView.contentInset = UIEdgeInsets(top: 0,left: 0,bottom: 32,right: 0)
}

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! MovieCell
    //cell.imageView.imageFromURL(urlString: imageNames[indexPath.row])

    let image = UIImageView(image: UIImage(named: "img-logo"))
    image.contentMode = .scaleAspectFit
    image.frame = cell.containerView.bounds
    image.layer.cornerRadius = 10;
    image.clipsToBounds = true;
    image.imageFromURL(urlString: imageNames[indexPath.row])
    cell.containerView.addSubview(image)
    cell.containerView.backgroundColor = UIColor.init(hex: "232637")

    return cell
}

}

А мой UICollectionViewCell выглядит так:

class MovieCell: UICollectionViewCell {

@IBOutlet weak var containerView: UIView!

}

Мои представления выглядят так:

Мои представления выглядят так


person Ruben Aalders    schedule 23.04.2018    source источник


Ответы (1)


Похоже, вы не принимаете во внимание тот факт, что ячейки (ячейки табличного представления, а также ячейки представления коллекции) повторно используются. Таким образом, если табличное представление содержит представление коллекции, и вы прокручиваете это представление коллекции, а затем прокручиваете представление таблицы, ячейка представления таблицы повторно используется в новой строке, а ранее прокручиваемое представление коллекции внутри нее остается прокрученным до того места, где вы его поместили ранее. . Если это не то, что вы хотите, вы можете сбросить положение прокрутки представления коллекции, когда обнаружите, что ячейка используется повторно.

Что дало мне подсказку о том, что вы, возможно, не понимаете повторное использование ячеек, так это эта строка:

 cell.containerView.addSubview(image)

Это неправильно, потому что вы делаете это, даже если ячейка используется повторно, а это означает, что в некоторых из ваших ячеек будут десятки изображений, накладывающихся друг на друга, что замедляет работу и, в конечном итоге, может привести к нехватке памяти. Это не та проблема, о которой вы спрашивали, но это признак того, что вы не знаете о последствиях повторного использования ячеек.

person matt    schedule 23.04.2018
comment
Ах да, вы правы, что я этого не учел. Сейчас я исправил большую часть конструкции. Но я не могу найти никаких возможных решений, чтобы сохранить положение прокрутки прокручиваемых строк и позволить другим начинать с начала своего списка. У Вас есть какие-то предложения? - person Ruben Aalders; 24.04.2018
comment
Как и все остальное в строке, это должно быть частью данных вашей модели. - person matt; 24.04.2018
comment
Я до сих пор понятия не имею и не могу найти какие-либо полезные примеры/учебники. Не могли бы вы указать мне правильное направление? - person Ruben Aalders; 25.04.2018
comment
Извините, я не хотел быть загадочным. Я просто предполагаю, что насколько далеко представление коллекции прокручивается в этой строке, так же, как представление изображения появляется в этой строке в this или значение шагового двигателя для этой строки в этом, или пользователь установил UISwitch в этой строке в этом. Все, что пользователь делает в строке, должно быть сохранено в вашей модели данных, чтобы ее можно было восстановить всякий раз, когда запрашивается ячейка для этой строки. - person matt; 25.04.2018
comment
Например. в этом простом примере: github.com /mattneub/Programming-iOS-Book-Examples/blob/master/ у нас есть редактируемые текстовые поля в каждой ячейке, поэтому я делаю контроллер представления делегатом текстовых полей, чтобы я мог сохранять изменения пользователя в модели (например, self.people, см. textFieldDidEndEditing). Я просто предполагаю, что пользователь, прокручивающий представление коллекции в строке вашей таблицы, может быть таким: пользовательская настройка, относящаяся к этой строке, которую вам, возможно, потребуется записать в модель данных и восстановить в cellForRow. - person matt; 25.04.2018
comment
Я вижу, это имеет смысл. Большое спасибо за всю помощь, которую вы оказали. - person Ruben Aalders; 25.04.2018