Swift 3- How to get button in UICollectionViewCell work
A very reliable and flexible pattern is to assign a "Callback Closure" to your cell. Put your button action handler inside the cell, and have it "call back" to the view controller.
Here is a basic example (you should be able to implement it with your custom cell with no problem):
//
// CViewWithButtonCollectionViewController.swift
// SWTemp2
//
// Created by Don Mag on 6/5/17.
// Copyright © 2017 DonMag. All rights reserved.
//
import UIKit
private let reuseIdentifier = "ImgItemCell"
class ImgItemCell: UICollectionViewCell {
// this will be our "call back" action
var btnTapAction : (()->())?
override init(frame: CGRect){
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupViews()
}
let editButton: UIButton = {
let button = UIButton(type: UIButtonType.system)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .white
button.setTitle("Edit", for: .normal)
return button
}()
func setupViews(){
// add a button
addSubview(editButton)
editButton.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
editButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
// add the touchUpInside target
editButton.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
}
@objc func btnTapped() {
print("Tapped!")
// use our "call back" action to tell the controller the button was tapped
btnTapAction?()
}
}
class CViewWithButtonCollectionViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let layout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
layout.itemSize = CGSize(width: 300, height: 100)
}
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ImgItemCell
cell.backgroundColor = .red
// set a "Callback Closure" in the cell
cell.btnTapAction = {
() in
print("Edit tapped in cell", indexPath)
// start your edit process here...
}
return cell
}
}
Swift 3 Button in UICollectionViewCell not respond to touch
I dont know why!? But i create another cell with same config that worked fine!!!!
UICollectionView with buttons
Assign the tag
and action
to the button inside the collectionviewcell
.
Assign indexPath.item
as button tag is the best approach to identify the particular button from the number of cells.
All you need to do within cellForItemAt
delegate method.
cell.btnCounter.tag = indexPath.item
cell.btnCounter.addTarget(self, action: #selector(self.buttonClicked), for: .touchUpInside)
And now you just need to handle the event as below
func buttonClicked(_ sender: UIButton) {
//Here sender.tag will give you the tapped Button index from the cell
//You can identify the button from the tag
}
How get product code when pressed button on uicollectionViewCell?
you can use with tag concept for identify which object you are pressed,
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
........
let productCode = productsObjectArray[indexPath.item].code
cell.favoriteBtn1.tag = indexPath.item
cell.favoriteBtn1.addTarget(self, action: #selector(didTapButton(_:)), for: .touchUpInside)
}
and your button action
@objc func didTapButton(_ sender: UIButton) {
let productCode = productsObjectArray[sender.tag].code
print("clicked product id: ", productCode)
}
How to add uibutton action in a collection view cell?
May be needful for you-
Write this code in cellForItemAtIndexPath
Swift 2.X
let editButton = UIButton(frame: CGRectMake(0, 20, 40,40))
editButton.setImage(UIImage(named: "editButton.png"), forState: UIControlState.Normal)
editButton.addTarget(self, action: #selector(editButtonTapped), forControlEvents: UIControlEvents.TouchUpInside)
cell.addSubview(editButton)
Swift 3.X
let editButton = UIButton(frame: CGRect(x:0, y:20, width:40,height:40))
editButton.setImage(UIImage(named: "editButton.png"), for: UIControlState.normal)
editButton.addTarget(self, action: #selector(editButtonTapped), for: UIControlEvents.touchUpInside)
cell.addSubview(editButton)
And perform your action-
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func editButtonTapped() -> Void {
print("Hello Edit Button")
}
How do I get a UIButton press to work in a UICollectionViewCell in Swift?
So, I figured out how to solve this, although it's somewhat of a workaround. Basically for the UICollectionView
I need to ensure the cell's can't get focus.
Next I had didUpdateFocusInContext
in CustomCell
previously. This was what was actually animating the button when the cell, but when I checked the button never got focus. I'm guessing this was intercepting it. So I removed that function from CustomCell
and instead, at the bottom of my file I added that function as an extension of UIButton.
This also could've been done by creating a subclass of UIButton
and using that instead, but this was less code (that is probably the ideal way). So the full code looks like:
class MyCollection: UICollectionView, UICollectionViewDelegate {
// Need initializer functions as well as functions for creating CustomCell's. They're omitted because they're not relevant to the answer
func collectionView(collectionView: UICollectionView, canFocusItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
}
class CustomCell: UICollectionViewCell {
var button:UIButton!
override init(frame: CGRect) {
super.init(frame: frame)
button = UIButton(...) // Button is initialized with a frame
button.userInteractionEnabled = true
button.enabled = true
button.addTarget(self, action: "pressed:", forControlEvents: .PrimaryActionTriggered)
self.addSubview(button)
}
func pressed(sender: UIButton!) {
print("button pressed!")
}
}
extension UIButton {
override public func didUpdateFocusInContext(context: UIFocusUpdateContext, withAnimationCoordinator coordinator: UIFocusAnimationCoordinator) {
super.didUpdateFocusInContext(context, withAnimationCoordinator: coordinator)
if self.superview is CustomCell { // This ensures that all UIButtons aren't affected
if context.nextFocusedView == self {
// Perform actions for when UIButton is focused
}else {
// Perform actions for when UIButton loses focus
}
}
}
}
Swift 3: button on collectionview
on cellForItem add the action as a selector to your custom button which you added to your custom cell like this
cell?.customButton.addTarget(self, action: #selector(masterCellAction), for: .touchUpInside)
Edit:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
cell.masterButton.addTarget(self,action: #selector(masterAction(_:)),for: .touchUpInside)
return cell
}
func masterAction(_ sender: UIButton)
{
let indexPath = collectionView?.indexPath(for: ((sender.superview?.superview) as! CounterCollectionViewCell))
let presentCounter = counters[indexPath.row] presentCounter.valueCD = presentCounter.valueCD + 1
}
Related Topics
Swift Framework Does Not Include Symbols from Extensions to Generic Structs
Autolayout: Uiview Within Uiview Has Incorrect Frame
Set the Status Bar to Black Colour
Nsurlcache Does Not Clear Stored Responses in iOS8
Simple Sprite Kit Scene Setup Going Wrong
Error Using Swift - Instance Member Cannot Be Used on Type 'Viewcontroller'
How to Launch My Settings Bundle from My Application
How to Hide a Bar Button Item for Certain Users
How to Capture Taps Ignored by Wkwebview
Uiapplicationlaunchoptionsremotenotificationkey Not Getting Userinfo