Swift 3- How to Get Button in Uicollectionviewcell Work

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



Leave a reply



Submit