I have collectionView inside TableViewCell. TableView has 1 section and 4 rows.
我在TableViewCell中有collectionView。 TableView有1个部分和4个行。
I want to figure out which row of tableviewcell is selected when collectionView is Scrolled Horizontally.
我想弄清楚当collectionView水平滚动时选择了哪一行tableviewcell。
I tryed to figure out by putting tableView row in "var nowRow" variable like below code. But It does not work.
我试着把tableView行放在“var nowRow”变量中,就像下面的代码一样。但它不起作用。
How can I find out which row of tableviewcell is selected?
如何找出选择哪一行tableviewcell?
class Home2ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate {
var posts = [Post]()
var nowRow = Int()
override func viewDidLoad() {
// get posts elements here
//posts.append(element).......
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count // 4counts
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = DetailMutiTableViewCell()
let cell = tableView.dequeueReusableCell(withIdentifier: "DetailMutiTableViewCell", for: indexPath) as! DetailMutiTableViewCell
nowRow = indexPath.row
cell.post = posts[nowRow]
cell.collectionView1.delegate = self
cell.collectionView1.dataSource = self
cell.collectionView1.reloadData()
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts[nowRow].imageUrls.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MultiImagesCollectionViewCell", for: indexPath) as! MultiImagesCollectionViewCell
let photoUrlString = posts[nowRow].imageUrls[indexPath.item] // ←error occured
let photoUrl = URL(string: photoUrlString)
cell.imageView1.sd_setImage(with: photoUrl)
return cell
}
}
editeditedit
1 个解决方案
#1
0
As you have no doubt discovered, interacting with the collectionViews in your table rows does not trigger the tableView method tableView(_:didSelectRowAt:)
, and tableView.indexPathForSelectedRow
is nil
because no row has been selected. You need a way to map from the collectionView
to the indexPath.row
that contains it. This information is known at tableViewCell
setup time.
毫无疑问,发现与表行中的collectionViews交互不会触发tableView方法tableView(_:didSelectRowAt :),并且tableView.indexPathForSelectedRow为nil,因为没有选择任何行。您需要一种从collectionView映射到包含它的indexPath.row的方法。此信息在tableViewCell设置时已知。
Add a dictionary to your Home2ViewController
that maps a UICollectionView
to a row Int
:
在Home2ViewController中添加一个字典,将UICollectionView映射到行Int:
var collectionViewRow = [UICollectionView : Int]()
Add the entries in tableView(_:cellForRowAt:)
where you know the row
and collectionView
:
在tableView(_:cellForRowAt :)中添加条目,您知道row和collectionView:
collectionViewRow[cell.collectionView1] = indexPath.row
Then, anytime you have a collectionView
, you can look up its row:
然后,只要你有一个collectionView,你就可以查找它的行:
let row = collectionViewRow[collectionView]!
Here's the whole code:
这是整个代码:
class Home2ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate {
var posts = [Post]()
var collectionViewRow = [UICollectionView : Int]()
override func viewDidLoad() {
// get posts elements here
//posts.append(element).......
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count // 4counts
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = DetailMutiTableViewCell()
let cell = tableView.dequeueReusableCell(withIdentifier: "DetailMutiTableViewCell", for: indexPath) as! DetailMutiTableViewCell
collectionViewRow[cell.collectionView1] = indexPath.row
cell.post = posts[indexPath.row]
cell.collectionView1.delegate = self
cell.collectionView1.dataSource = self
cell.collectionView1.reloadData()
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let row = collectionViewRow[collectionView]!
return posts[row].imageUrls.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MultiImagesCollectionViewCell", for: indexPath) as! MultiImagesCollectionViewCell
let row = collectionViewRow[collectionView]!
let photoUrlString = posts[row].imageUrls[indexPath.item] // ←error occured
let photoUrl = URL(string: photoUrlString)
cell.imageView1.sd_setImage(with: photoUrl)
return cell
}
}
Notes:
- The force unwrap of the dictionary lookup won't fail because the
collectionView
will be in there. If you want to unwrap it withif let
, you'll need to decide what to do when you don't get a row (which shouldn't happen). - This method could fail if your table allows editing (user can rearrange order of rows or delete rows). If you don't support editing, then this will work fine. To support editing, you could change the dictionary to
[UICollectionView : UITableViewCell]
. Then, given aUICollectionView
, you could look up itscell
, and then calllet indexPath = tableView.indexPath(for: cell)
to get theindexPath
and your row is then justindexPath.row
.
字典查找的强制解包不会失败,因为collectionView将在那里。如果你想用let打开它,你需要决定当你没有得到一行时该做什么(这不应该发生)。
如果您的表允许编辑(用户可以重新排列行的顺序或删除行),此方法可能会失败。如果你不支持编辑,那么这将正常工作。要支持编辑,您可以将字典更改为[UICollectionView:UITableViewCell]。然后,给定一个UICollectionView,你可以查找它的单元格,然后调用let indexPath = tableView.indexPath(for:cell)来获取indexPath,然后你的行只是indexPath.row。
#1
0
As you have no doubt discovered, interacting with the collectionViews in your table rows does not trigger the tableView method tableView(_:didSelectRowAt:)
, and tableView.indexPathForSelectedRow
is nil
because no row has been selected. You need a way to map from the collectionView
to the indexPath.row
that contains it. This information is known at tableViewCell
setup time.
毫无疑问,发现与表行中的collectionViews交互不会触发tableView方法tableView(_:didSelectRowAt :),并且tableView.indexPathForSelectedRow为nil,因为没有选择任何行。您需要一种从collectionView映射到包含它的indexPath.row的方法。此信息在tableViewCell设置时已知。
Add a dictionary to your Home2ViewController
that maps a UICollectionView
to a row Int
:
在Home2ViewController中添加一个字典,将UICollectionView映射到行Int:
var collectionViewRow = [UICollectionView : Int]()
Add the entries in tableView(_:cellForRowAt:)
where you know the row
and collectionView
:
在tableView(_:cellForRowAt :)中添加条目,您知道row和collectionView:
collectionViewRow[cell.collectionView1] = indexPath.row
Then, anytime you have a collectionView
, you can look up its row:
然后,只要你有一个collectionView,你就可以查找它的行:
let row = collectionViewRow[collectionView]!
Here's the whole code:
这是整个代码:
class Home2ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate {
var posts = [Post]()
var collectionViewRow = [UICollectionView : Int]()
override func viewDidLoad() {
// get posts elements here
//posts.append(element).......
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count // 4counts
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = DetailMutiTableViewCell()
let cell = tableView.dequeueReusableCell(withIdentifier: "DetailMutiTableViewCell", for: indexPath) as! DetailMutiTableViewCell
collectionViewRow[cell.collectionView1] = indexPath.row
cell.post = posts[indexPath.row]
cell.collectionView1.delegate = self
cell.collectionView1.dataSource = self
cell.collectionView1.reloadData()
return cell
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let row = collectionViewRow[collectionView]!
return posts[row].imageUrls.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MultiImagesCollectionViewCell", for: indexPath) as! MultiImagesCollectionViewCell
let row = collectionViewRow[collectionView]!
let photoUrlString = posts[row].imageUrls[indexPath.item] // ←error occured
let photoUrl = URL(string: photoUrlString)
cell.imageView1.sd_setImage(with: photoUrl)
return cell
}
}
Notes:
- The force unwrap of the dictionary lookup won't fail because the
collectionView
will be in there. If you want to unwrap it withif let
, you'll need to decide what to do when you don't get a row (which shouldn't happen). - This method could fail if your table allows editing (user can rearrange order of rows or delete rows). If you don't support editing, then this will work fine. To support editing, you could change the dictionary to
[UICollectionView : UITableViewCell]
. Then, given aUICollectionView
, you could look up itscell
, and then calllet indexPath = tableView.indexPath(for: cell)
to get theindexPath
and your row is then justindexPath.row
.
字典查找的强制解包不会失败,因为collectionView将在那里。如果你想用let打开它,你需要决定当你没有得到一行时该做什么(这不应该发生)。
如果您的表允许编辑(用户可以重新排列行的顺序或删除行),此方法可能会失败。如果你不支持编辑,那么这将正常工作。要支持编辑,您可以将字典更改为[UICollectionView:UITableViewCell]。然后,给定一个UICollectionView,你可以查找它的单元格,然后调用let indexPath = tableView.indexPath(for:cell)来获取indexPath,然后你的行只是indexPath.row。