How to get index on button click of collectionview cell which is inside tableview cell
I have a collectionView embedded in tableView cell. CollectionView has multiple items, which contains button. Collection View datasource and delegates are getting set in UITableViewCell. I have to perform some action based on that button selection for that, I need to know collectionView cell indexPath and tableView cell indexPath. But not able to figure out, how to achieve this. Tried using delegates, but don't know how to get collectionView reference in delegate method.
CollectionView Cell
protocol SelectedItemCellDelegate:class {
func deleteButtonDidTapped(_ cell: SelectedItemCell)
}
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
weak var delegate: SelectedItemCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func deleteAction(_ sender: Any) {
delegate?.deleteButtonDidTapped(self)
}
}
ViewController
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.delegate = self
return cell
}
extension PrescriptionVC: SelectedItemCellDelegate
{
func deleteButtonDidTapped(_ cell: SelectedItemCell)
{
// Need tableview indexPath as well SelectedItemCell indexPath.
}
}
ios swift uitableview uicollectionview
add a comment |
I have a collectionView embedded in tableView cell. CollectionView has multiple items, which contains button. Collection View datasource and delegates are getting set in UITableViewCell. I have to perform some action based on that button selection for that, I need to know collectionView cell indexPath and tableView cell indexPath. But not able to figure out, how to achieve this. Tried using delegates, but don't know how to get collectionView reference in delegate method.
CollectionView Cell
protocol SelectedItemCellDelegate:class {
func deleteButtonDidTapped(_ cell: SelectedItemCell)
}
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
weak var delegate: SelectedItemCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func deleteAction(_ sender: Any) {
delegate?.deleteButtonDidTapped(self)
}
}
ViewController
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.delegate = self
return cell
}
extension PrescriptionVC: SelectedItemCellDelegate
{
func deleteButtonDidTapped(_ cell: SelectedItemCell)
{
// Need tableview indexPath as well SelectedItemCell indexPath.
}
}
ios swift uitableview uicollectionview
add a comment |
I have a collectionView embedded in tableView cell. CollectionView has multiple items, which contains button. Collection View datasource and delegates are getting set in UITableViewCell. I have to perform some action based on that button selection for that, I need to know collectionView cell indexPath and tableView cell indexPath. But not able to figure out, how to achieve this. Tried using delegates, but don't know how to get collectionView reference in delegate method.
CollectionView Cell
protocol SelectedItemCellDelegate:class {
func deleteButtonDidTapped(_ cell: SelectedItemCell)
}
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
weak var delegate: SelectedItemCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func deleteAction(_ sender: Any) {
delegate?.deleteButtonDidTapped(self)
}
}
ViewController
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.delegate = self
return cell
}
extension PrescriptionVC: SelectedItemCellDelegate
{
func deleteButtonDidTapped(_ cell: SelectedItemCell)
{
// Need tableview indexPath as well SelectedItemCell indexPath.
}
}
ios swift uitableview uicollectionview
I have a collectionView embedded in tableView cell. CollectionView has multiple items, which contains button. Collection View datasource and delegates are getting set in UITableViewCell. I have to perform some action based on that button selection for that, I need to know collectionView cell indexPath and tableView cell indexPath. But not able to figure out, how to achieve this. Tried using delegates, but don't know how to get collectionView reference in delegate method.
CollectionView Cell
protocol SelectedItemCellDelegate:class {
func deleteButtonDidTapped(_ cell: SelectedItemCell)
}
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
weak var delegate: SelectedItemCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func deleteAction(_ sender: Any) {
delegate?.deleteButtonDidTapped(self)
}
}
ViewController
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.delegate = self
return cell
}
extension PrescriptionVC: SelectedItemCellDelegate
{
func deleteButtonDidTapped(_ cell: SelectedItemCell)
{
// Need tableview indexPath as well SelectedItemCell indexPath.
}
}
ios swift uitableview uicollectionview
ios swift uitableview uicollectionview
asked Nov 22 at 18:22
Xcoder
517
517
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure
In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
var callback : (()->Void)?
@IBAction func deleteAction(_ sender: Any) {
callback?()
}
}
In the controller set the closure and handle the callback, the index path is captured.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.callback {
print("button pressed", indexPath)
}
return cell
}
add a comment |
You need two delegates
protocol selectCollectionCellDelegate {
func selectCell(cell : UICollectionViewCell )
}
protocol selectTableCellDelegate {
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath )
}
class YourCollectionViewCell : UICollectionViewCell {
var tvcDelegate : selectCollectionCellDelegate
@IBAction func deleteAction(_ sender: Any) {
tvcDelegate.selectCell(cell : self)
}
}
class YourTableViewCell : UITableViewCell , selectCollectionCellDelegate {
var vcDelegate : selectTableCellDelegate
func selectCell(cell : UICollectionViewCell ){
let indexPath : IndexPath = collectionView.indexPath(for: cell)!
delegate.selectTableCell(cell : self , indexPath : indexPath )
}
}
class YourviewController : UIViewController , selectTableCellDelegate{
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath){
//indexPatn is IndexPath of collectionViewCell
let tableCellindexPath : IndexPath = tableView.indexPath(for: self)!
}
}
add a comment |
In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:
protocol SelectedItemCellDelegate:class {
func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
}
Rewrite your deleteAction to pass sender as UIButton
class (or any UIView
class)
@IBAction func deleteAction(_ sender: UIButton) {
delegate?. deleteButton(sender, tappedInCell: self)
}
Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:
extension UICollectionView {
func indexPathForCellContaining( view: UIView) -> IndexPath? {
let viewCenter = self.convert(view.center, from: view.superview)
return self.indexPathForItem(at: viewCenter)
}
}
Or for table views:
public extension UITableView {
/**
This method returns the indexPath of the cell that contains the specified view
- Parameter view: The view to find.
- Returns: The indexPath of the cell containing the view, or nil if it can't be found
*/
func indexPathForView(_ view: UIView) -> IndexPath? {
let center = view.center
//The center of the view is a better point to use, but we can only use it if the view has a superview
guard let superview = view.superview else {
//The view we were passed does not have a valid superview.
//Use the view's bounds.origin and convert from the view's coordinate system
let origin = self.convert(view.bounds.origin, from: view)
let indexPath = self.indexPathForRow(at: origin)
return indexPath
}
let viewCenter = self.convert(center, from: superview)
let indexPath = self.indexPathForRow(at: viewCenter)
return indexPath
}
}
Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell)
to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.
I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
– Xcoder
Nov 22 at 21:28
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436418%2fhow-to-get-index-on-button-click-of-collectionview-cell-which-is-inside-tablevie%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure
In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
var callback : (()->Void)?
@IBAction func deleteAction(_ sender: Any) {
callback?()
}
}
In the controller set the closure and handle the callback, the index path is captured.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.callback {
print("button pressed", indexPath)
}
return cell
}
add a comment |
You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure
In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
var callback : (()->Void)?
@IBAction func deleteAction(_ sender: Any) {
callback?()
}
}
In the controller set the closure and handle the callback, the index path is captured.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.callback {
print("button pressed", indexPath)
}
return cell
}
add a comment |
You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure
In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
var callback : (()->Void)?
@IBAction func deleteAction(_ sender: Any) {
callback?()
}
}
In the controller set the closure and handle the callback, the index path is captured.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.callback {
print("button pressed", indexPath)
}
return cell
}
You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure
In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
var callback : (()->Void)?
@IBAction func deleteAction(_ sender: Any) {
callback?()
}
}
In the controller set the closure and handle the callback, the index path is captured.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.callback {
print("button pressed", indexPath)
}
return cell
}
edited Nov 23 at 9:08
answered Nov 23 at 9:03
vadian
142k13151168
142k13151168
add a comment |
add a comment |
You need two delegates
protocol selectCollectionCellDelegate {
func selectCell(cell : UICollectionViewCell )
}
protocol selectTableCellDelegate {
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath )
}
class YourCollectionViewCell : UICollectionViewCell {
var tvcDelegate : selectCollectionCellDelegate
@IBAction func deleteAction(_ sender: Any) {
tvcDelegate.selectCell(cell : self)
}
}
class YourTableViewCell : UITableViewCell , selectCollectionCellDelegate {
var vcDelegate : selectTableCellDelegate
func selectCell(cell : UICollectionViewCell ){
let indexPath : IndexPath = collectionView.indexPath(for: cell)!
delegate.selectTableCell(cell : self , indexPath : indexPath )
}
}
class YourviewController : UIViewController , selectTableCellDelegate{
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath){
//indexPatn is IndexPath of collectionViewCell
let tableCellindexPath : IndexPath = tableView.indexPath(for: self)!
}
}
add a comment |
You need two delegates
protocol selectCollectionCellDelegate {
func selectCell(cell : UICollectionViewCell )
}
protocol selectTableCellDelegate {
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath )
}
class YourCollectionViewCell : UICollectionViewCell {
var tvcDelegate : selectCollectionCellDelegate
@IBAction func deleteAction(_ sender: Any) {
tvcDelegate.selectCell(cell : self)
}
}
class YourTableViewCell : UITableViewCell , selectCollectionCellDelegate {
var vcDelegate : selectTableCellDelegate
func selectCell(cell : UICollectionViewCell ){
let indexPath : IndexPath = collectionView.indexPath(for: cell)!
delegate.selectTableCell(cell : self , indexPath : indexPath )
}
}
class YourviewController : UIViewController , selectTableCellDelegate{
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath){
//indexPatn is IndexPath of collectionViewCell
let tableCellindexPath : IndexPath = tableView.indexPath(for: self)!
}
}
add a comment |
You need two delegates
protocol selectCollectionCellDelegate {
func selectCell(cell : UICollectionViewCell )
}
protocol selectTableCellDelegate {
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath )
}
class YourCollectionViewCell : UICollectionViewCell {
var tvcDelegate : selectCollectionCellDelegate
@IBAction func deleteAction(_ sender: Any) {
tvcDelegate.selectCell(cell : self)
}
}
class YourTableViewCell : UITableViewCell , selectCollectionCellDelegate {
var vcDelegate : selectTableCellDelegate
func selectCell(cell : UICollectionViewCell ){
let indexPath : IndexPath = collectionView.indexPath(for: cell)!
delegate.selectTableCell(cell : self , indexPath : indexPath )
}
}
class YourviewController : UIViewController , selectTableCellDelegate{
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath){
//indexPatn is IndexPath of collectionViewCell
let tableCellindexPath : IndexPath = tableView.indexPath(for: self)!
}
}
You need two delegates
protocol selectCollectionCellDelegate {
func selectCell(cell : UICollectionViewCell )
}
protocol selectTableCellDelegate {
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath )
}
class YourCollectionViewCell : UICollectionViewCell {
var tvcDelegate : selectCollectionCellDelegate
@IBAction func deleteAction(_ sender: Any) {
tvcDelegate.selectCell(cell : self)
}
}
class YourTableViewCell : UITableViewCell , selectCollectionCellDelegate {
var vcDelegate : selectTableCellDelegate
func selectCell(cell : UICollectionViewCell ){
let indexPath : IndexPath = collectionView.indexPath(for: cell)!
delegate.selectTableCell(cell : self , indexPath : indexPath )
}
}
class YourviewController : UIViewController , selectTableCellDelegate{
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath){
//indexPatn is IndexPath of collectionViewCell
let tableCellindexPath : IndexPath = tableView.indexPath(for: self)!
}
}
edited Nov 22 at 20:58
Paulw11
66.8k1081101
66.8k1081101
answered Nov 22 at 20:42
Ammar
1678
1678
add a comment |
add a comment |
In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:
protocol SelectedItemCellDelegate:class {
func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
}
Rewrite your deleteAction to pass sender as UIButton
class (or any UIView
class)
@IBAction func deleteAction(_ sender: UIButton) {
delegate?. deleteButton(sender, tappedInCell: self)
}
Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:
extension UICollectionView {
func indexPathForCellContaining( view: UIView) -> IndexPath? {
let viewCenter = self.convert(view.center, from: view.superview)
return self.indexPathForItem(at: viewCenter)
}
}
Or for table views:
public extension UITableView {
/**
This method returns the indexPath of the cell that contains the specified view
- Parameter view: The view to find.
- Returns: The indexPath of the cell containing the view, or nil if it can't be found
*/
func indexPathForView(_ view: UIView) -> IndexPath? {
let center = view.center
//The center of the view is a better point to use, but we can only use it if the view has a superview
guard let superview = view.superview else {
//The view we were passed does not have a valid superview.
//Use the view's bounds.origin and convert from the view's coordinate system
let origin = self.convert(view.bounds.origin, from: view)
let indexPath = self.indexPathForRow(at: origin)
return indexPath
}
let viewCenter = self.convert(center, from: superview)
let indexPath = self.indexPathForRow(at: viewCenter)
return indexPath
}
}
Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell)
to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.
I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
– Xcoder
Nov 22 at 21:28
add a comment |
In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:
protocol SelectedItemCellDelegate:class {
func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
}
Rewrite your deleteAction to pass sender as UIButton
class (or any UIView
class)
@IBAction func deleteAction(_ sender: UIButton) {
delegate?. deleteButton(sender, tappedInCell: self)
}
Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:
extension UICollectionView {
func indexPathForCellContaining( view: UIView) -> IndexPath? {
let viewCenter = self.convert(view.center, from: view.superview)
return self.indexPathForItem(at: viewCenter)
}
}
Or for table views:
public extension UITableView {
/**
This method returns the indexPath of the cell that contains the specified view
- Parameter view: The view to find.
- Returns: The indexPath of the cell containing the view, or nil if it can't be found
*/
func indexPathForView(_ view: UIView) -> IndexPath? {
let center = view.center
//The center of the view is a better point to use, but we can only use it if the view has a superview
guard let superview = view.superview else {
//The view we were passed does not have a valid superview.
//Use the view's bounds.origin and convert from the view's coordinate system
let origin = self.convert(view.bounds.origin, from: view)
let indexPath = self.indexPathForRow(at: origin)
return indexPath
}
let viewCenter = self.convert(center, from: superview)
let indexPath = self.indexPathForRow(at: viewCenter)
return indexPath
}
}
Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell)
to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.
I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
– Xcoder
Nov 22 at 21:28
add a comment |
In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:
protocol SelectedItemCellDelegate:class {
func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
}
Rewrite your deleteAction to pass sender as UIButton
class (or any UIView
class)
@IBAction func deleteAction(_ sender: UIButton) {
delegate?. deleteButton(sender, tappedInCell: self)
}
Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:
extension UICollectionView {
func indexPathForCellContaining( view: UIView) -> IndexPath? {
let viewCenter = self.convert(view.center, from: view.superview)
return self.indexPathForItem(at: viewCenter)
}
}
Or for table views:
public extension UITableView {
/**
This method returns the indexPath of the cell that contains the specified view
- Parameter view: The view to find.
- Returns: The indexPath of the cell containing the view, or nil if it can't be found
*/
func indexPathForView(_ view: UIView) -> IndexPath? {
let center = view.center
//The center of the view is a better point to use, but we can only use it if the view has a superview
guard let superview = view.superview else {
//The view we were passed does not have a valid superview.
//Use the view's bounds.origin and convert from the view's coordinate system
let origin = self.convert(view.bounds.origin, from: view)
let indexPath = self.indexPathForRow(at: origin)
return indexPath
}
let viewCenter = self.convert(center, from: superview)
let indexPath = self.indexPathForRow(at: viewCenter)
return indexPath
}
}
Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell)
to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.
In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:
protocol SelectedItemCellDelegate:class {
func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
}
Rewrite your deleteAction to pass sender as UIButton
class (or any UIView
class)
@IBAction func deleteAction(_ sender: UIButton) {
delegate?. deleteButton(sender, tappedInCell: self)
}
Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:
extension UICollectionView {
func indexPathForCellContaining( view: UIView) -> IndexPath? {
let viewCenter = self.convert(view.center, from: view.superview)
return self.indexPathForItem(at: viewCenter)
}
}
Or for table views:
public extension UITableView {
/**
This method returns the indexPath of the cell that contains the specified view
- Parameter view: The view to find.
- Returns: The indexPath of the cell containing the view, or nil if it can't be found
*/
func indexPathForView(_ view: UIView) -> IndexPath? {
let center = view.center
//The center of the view is a better point to use, but we can only use it if the view has a superview
guard let superview = view.superview else {
//The view we were passed does not have a valid superview.
//Use the view's bounds.origin and convert from the view's coordinate system
let origin = self.convert(view.bounds.origin, from: view)
let indexPath = self.indexPathForRow(at: origin)
return indexPath
}
let viewCenter = self.convert(center, from: superview)
let indexPath = self.indexPathForRow(at: viewCenter)
return indexPath
}
}
Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell)
to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.
answered Nov 22 at 20:12
Duncan C
91.8k13114195
91.8k13114195
I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
– Xcoder
Nov 22 at 21:28
add a comment |
I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
– Xcoder
Nov 22 at 21:28
I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
– Xcoder
Nov 22 at 21:28
I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
– Xcoder
Nov 22 at 21:28
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436418%2fhow-to-get-index-on-button-click-of-collectionview-cell-which-is-inside-tablevie%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown