Выбор невозможен, когда UICollectionView вложен в UITableVIew
У меня есть UITableView
где каждая клетка содержит UICollectionView
,
Я могу прокрутить UITableView
вертикально и прокручивать вложенные UICollectionView
по горизонтали, однако я не могу выбрать UICollectionViewCell
в UICollectionView
,
Выбор отключен в UITableView
и включен (состояние по умолчанию) в UICcollectionView
,
UICollectionView's
collectionView:didSelectItemAtIndexPath:
просто никогда не звонил.
9 ответов
Все просмотры, которые у вас есть в кастомном
UITableViewCell
должны быть размещены относительно формата. Поэтому всегда добавляйте их как подвид к
contentView
и выбор должен работать.
class CustomTableViewCell: UITableViewCell {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
let view = UIView()
contentView.addSubview(view)
// layout
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Я только что заработал, поэтому решил, что поделюсь своим решением с вами, ребята.
После настройки необходимых делегатов и источников данных для UITableView
и вложенный UICollectionView
Вы можете сделать свой UICollectionView
первый выбираемый вид, как это
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
[tableViewCell bringSubviewToFront:tableViewCell.yourCollectionView];
return cell;
}
Это сделает UICollectionView
первое, что можно выбрать с помощью делегата
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
Любая другая часть представления будет выбрана с помощью UITableView
делегат
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
Надеюсь это поможет!
Я смог решить эту проблему, добавив в ячейку распознаватель жестов касания, чтобы обрабатывать касание вручную, а не полагаться на didSelectRowAtIndexPath
который не вызывается:
стриж
let tapRecognizer = UITapGestureRecognizer(target: self, action: "cellTapped:")
tapRecognizer.numberOfTapsRequired = 1
cell.addGestureRecognizer(tapRecognizer)
Objective-C
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cellTapped:)];
tapRecognizer.numberOfTapsRequired = 1;
[cell addGestureRecognizer:tapRecognizer];
Теперь вы можете обрабатывать ячейку в cellTapped:
метод, и вы можете получить ссылку на ячейку, которая была нажата через tapRecognizer.view
,
В представленииконтроллере
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!{
didSet{
tableView.delegate = self
tableView.dataSource = self
tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: TableViewCell.cellId)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
extension ViewController : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.cellId, for: indexPath) as! TableViewCell
return cell
}
}
В файле TableViewCell
import UIKit
class TableViewCell: UITableViewCell {
static let cellId = "TableViewCell"
@IBOutlet weak var collectionView: UICollectionView! {
didSet{
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: CollectionViewCell.cellId)
}
}
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
}
}
extension TableViewCell : UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.cellId, for: indexPath) as! CollectionViewCell
cell.labelThing.text = "samples text"
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Hello world")
}
}
В файле CollectionView
import UIKit
class CollectionViewCell: UICollectionViewCell {
static let cellId = "CollectionViewCell"
@IBOutlet weak var labelThing: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
Попробуй отключить delaysContentTouches
за tableView
и убедитесь, что delegate
для вашей коллекции представления установлены правильно.
Я проверил как с раскадровкой, так и программно, и он работает, как ожидалось. Я получаю collectionView: didSelectItemAtIndexPath: или tableView: didSelectRowAtIndexPath в зависимости от нажатой области. Кажется, что, по крайней мере, в более новых SDK (у меня это 11.4), это исправлено.
Мой первый инстинкт заключается в том, что распознаватели жестов между двумя представлениями могут конфликтовать
более конкретно, GR UITableView для ответвления могут препятствовать получению касаний GR UICollectionView.
Сначала проверьте, пожалуйста, вы предоставили необходимый источник данных и делегатов. Затем, если вы используете коллекционное представление для определенного количества ячеек табличного представления, вы можете напрямую поместить его в ячейку прототипа. Пожалуйста, убедитесь, что ваша ячейка имеет надлежащие пределы (ширина)
Это не должно быть проблемой вообще! не нужны специальные распознаватели жестов. нет необходимости отключать выбор таблицы.
обязательно:
- настроить табличное представление в раскадровке или коде и установить его источник данных и делегировать
- в cellforrowatindexpath после освобождения ячейки tableview получите ссылку на соответствующий view collection и установите его источник данных (collectionviews) и делегата
- реализовывать методы tablesev и collectionviews делегата didselect и регистрировать их вызовы, чтобы увидеть, как это работает
Я просто реализовал небольшой пример проекта, прежде чем написал этот ответ, чтобы убедиться, что нет проблем. Я могу загрузить его, если он все еще не работает для вас!
удачи!