So I have a cells in a collectionview with 3 buttons in it. To trigger code with these buttons I have implemented a custom delegate. Now the code is being triggered, but I don't know from which cell the code triggered. How can I best implement this? Here is some of my code.
Protocol:
protocol OverViewDelegate {
func registerButtonClicked()
func evaluateButtonClicked()
func overviewButtonClicked()
}
cellForItemAt:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "sessionCell", for: indexPath) as? SessionCollectionViewCell
let session: SessionModel
session = DebugData.shared.sessionArray[indexPath.row]
cell?.sessionImage.image = #imageLiteral(resourceName: "carControl")
cell?.sessionNameLabel.text = session.name
cell?.sessionLocationLabel.text = session.location
cell?.overViewDelegate = self
return cell!
}
cell:
import UIKit
import IBAnimatable
#IBOutlet weak var sessionImage: UIImageView!
#IBOutlet weak var sessionNameLabel: UILabel!
#IBOutlet weak var sessionLocationLabel: UILabel!
#IBOutlet weak var sessionRegisterButton: AnimatableButton!
#IBOutlet weak var sessionOverviewButton: AnimatableButton!
#IBOutlet weak var sessionEvaluateButton: AnimatableButton!
var overViewDelegate: OverViewDelegate?
#IBAction func registerButtonClicked(_ sender: Any) {
overViewDelegate?.registerButtonClicked()
}
#IBAction func overviewButtonClicked(_ sender: Any) {
overViewDelegate?.overviewButtonClicked()
}
#IBAction func evaluateButtonClicked(_ sender: Any) {
overViewDelegate?.evaluateButtonClicked()
}
Any help would be appriciated.
Pass indexPath value in Cell class return back indexPath on Button Click function
protocol:-
protocol OverViewDelegate {
func registerButtonClicked(_ indexPath : IndexPath)
func evaluateButtonClicked(_ indexPath : IndexPath)
func overviewButtonClicked(_ indexPath : IndexPath)
}
cellForItemAt:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "sessionCell", for: indexPath) as? SessionCollectionViewCell
let session: SessionModel
session = DebugData.shared.sessionArray[indexPath.row]
cell?.sessionImage.image = #imageLiteral(resourceName: "carControl")
cell?.sessionNameLabel.text = session.name
cell?.sessionLocationLabel.text = session.location
cell?.overViewDelegate = self
cell?.indexPath = indexPath
return cell!
}
cell:
#IBOutlet weak var sessionImage: UIImageView!
#IBOutlet weak var sessionNameLabel: UILabel!
#IBOutlet weak var sessionLocationLabel: UILabel!
#IBOutlet weak var sessionRegisterButton: AnimatableButton!
#IBOutlet weak var sessionOverviewButton: AnimatableButton!
#IBOutlet weak var sessionEvaluateButton: AnimatableButton!
var overViewDelegate: OverViewDelegate?
var indexPath : IndexPath?
#IBAction func registerButtonClicked(_ sender: Any) {
overViewDelegate?.registerButtonClicked(indexPath)
}
#IBAction func overviewButtonClicked(_ sender: Any) {
overViewDelegate?.overviewButtonClicked(indexPath)
}
#IBAction func evaluateButtonClicked(_ sender: Any) {
overViewDelegate?.evaluateButtonClicked(indexPath)
}
get cell using :-
let cell = tableView.cellForRow(at: indexPath)
The best way to do is in protocol method send back the cell..
for example
protocol OverViewDelegate {
func registerButtonClicked(cell: SessionCollectionViewCell)
func evaluateButtonClicked(cell: SessionCollectionViewCell)
func overviewButtonClicked(cell : SessionCollectionViewCell)
}
and on button click
#IBAction func overviewButtonClicked(_ sender: Any) {
overViewDelegate?.overviewButtonClicked(cell: self)
}
and on you viewcontroller when delegate method implemented
func overviewButtonClicked(cell: SessionCollectionViewCell) {
// here you get the cell and all the properties you want to access of that cell and also
if let indexPath = self.tableView.indexPath(for: cell) {
// do what you want to do
}
}
Put a variable in your cell and save your session data model instance in cellForRowAt. Then update your delegate methods and add for each method a session parameter.
So you have the instance of your data model for each button press
You can check with button tag in cellForItemAt:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "sessionCell", for: indexPath) as? SessionCollectionViewCell
cell.YOUR_BUTTON.tag = indexPath.item
return cell!
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "sessionCell", for: indexPath) as? SessionCollectionViewCell
let session: SessionModel
session = DebugData.shared.sessionArray[indexPath.row]
cell.sessionRegisterButton.tag = indexPath.row // --- add this
..........
cell?.sessionImage.image = #imageLiteral(resourceName: "carControl")
cell?.sessionNameLabel.text = session.name
cell?.sessionLocationLabel.text = session.location
cell?.overViewDelegate = self
return cell!
}
#IBAction func registerButtonClicked(_ sender: Any) {
let cellIndex = sender.tag // this will be the cell index
overViewDelegate?.registerButtonClicked()
}
In cellForItemAt: method you can specify tag value and when a button is tapped you can check sender.tag to check which button is tapped.
You can achieve it by giving tags to all button in cellForItemAt: as bellow
cell.sessionRegisterButton.tag = indexPath.item
cell.sessionOverviewButton.tag = indexPath.item
cell.sessionEvaluateButton.tag = indexPath.item
And get index back by :
#IBAction func registerButtonClicked(_ sender: Any) {
let senderButton : UIButton = sender as! UIButton
let index : Int = senderButton.tag
overViewDelegate?.registerButtonClicked()
}
#IBAction func overviewButtonClicked(_ sender: Any) {
let senderButton : UIButton = sender as! UIButton
let index : Int = senderButton.tag
overViewDelegate?.overviewButtonClicked()
}
#IBAction func evaluateButtonClicked(_ sender: Any) {
let senderButton : UIButton = sender as! UIButton
let index : Int = senderButton.tag
overViewDelegate?.evaluateButtonClicked()
}
Related
i have a view controller in which there is a tableview cell having button on it. Button with title add comments. when i click on add comments button then it take me to the next page where textfield is present when i write something in it then press done button then my button title for all the cell changes. But i want only selected row button title should change. Below is my code of table view.
class MyTabViewController: UIViewController {
var addCommentsValueStore: String = "Add Comments"
#IBOutlet weak var tabTableView : ContentWrappingTableView!
#IBAction func addCommentsAction(_ sender: UIButton) {
guard let nextVC = MyCommentsRouter.getMyCommentsViewScreen() else { return }
nextVC.passAddCommentsDelegate = self
self.navigationController?.pushViewController(nextVC, animated: true)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let indetifier = "MyTabTableViewCell"
let cell = tableView.dequeueReusableCell(withIdentifier: indetifier, for: indexPath) as! MyTabTableViewCell
cell.addCommentsButton.setTitle(addCommentsValueStore, for: UIControl.State.normal)
}
}
extension MyTabViewController: AddCommentsDelegate{
func passAddComments(instruction: String) {
addCommentsValueStore = instruction
print(addCommentsValueStore)
}
}
below is the code of next view controller:
import UIKit
protocol AddCommentsDelegate{
func passAddComments(instruction: String)
}
class MyCommentsViewController: UIViewController {
#IBOutlet var addCommentsTextField: UITextField!
var passAddCommentsDelegate: AddCommentsDelegate?
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func backActionClick(_ sender: UIButton) {
// guard let nextVC = MyTabRouter.getMyTabViewScreen() else { return }
self.navigationController?.popViewController(animated: true)
}
#IBAction func DoneActionClick(_ sender: Any) {
let dataToBeSent = addCommentsTextField.text
self.passAddCommentsDelegate?.passAddComments(instruction: dataToBeSent!)
self.navigationController?.popViewController(animated: true)
}
}
You can do it in this delegate method as below:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
for (id object in cell.superview.subviews) {
if ([object isKindOfClass:[UITableViewCell class]]) {
UITableViewCell *cellNotSelected = (UITableViewCell*)object;
cellNotSelected.textLabel.textColor = [UIColor blackColor];
}
}
cell.textLabel.textColor = [UIColor redColor];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
you need to change you logic for done those things. First you need to declare string Wrong. Because string only hold a single value. You need to declare variable as Dictionary [IndexPath:String] Or AnyHashable Dictionary for store the value. I will give reference code below feel free to refer and if any doubt in the code please ask me in command
Reference Code
import UIKit
class FirstViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var commend: [IndexPath: String] = [:]
}
extension FirstViewController: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ListTableViewCell.self), for: indexPath) as! ListTableViewCell
cell.button.setTitle(commend[indexPath] ?? "Add commend", for: .normal)
cell.label.text = "\(indexPath.row)"
cell.button.addTarget(self, action: #selector(self.addCommentsAction(_:)), for: .touchUpInside)
return cell
}
#objc func addCommentsAction(_ sender: UIButton) {
guard let nextVC = UIStoryboard(name: "Main", bundle: .some(.main)).instantiateViewController(withIdentifier: String(describing: CommendViewController.self)) as? CommendViewController else { return }
let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to: self.tableView)
guard let indexPath = self.tableView.indexPathForRow(at: buttonPosition) else{
return
}
nextVC.delegate = self
nextVC.indexPath = indexPath
self.navigationController?.pushViewController(nextVC, animated: true)
}
}
extension FirstViewController: DataPassingDelegate{
func commendForIndex(_ string: String, indexPath: IndexPath) {
self.commend[indexPath] = string
self.tableView.reloadData()
}
}
class ListTableViewCell: UITableViewCell{
#IBOutlet weak var label: UILabel!
#IBOutlet weak var button: UIButton!
}
protocol DataPassingDelegate: AnyObject {
func commendForIndex(_ string: String, indexPath: IndexPath)
}
class CommendViewController: UIViewController {
#IBOutlet weak var textView: UITextView!
weak var delegate: DataPassingDelegate?
var indexPath = IndexPath()
#IBAction func doneCommend(_ sender: UIButton){
self.delegate?.commendForIndex(textView.text, indexPath: indexPath)
self.navigationController?.popViewController(animated: true)
}
}
If I click button I want to pass label in button to the next view. Next view need navigationItem title with label from buttons in previous view.
I've tried segues, but it didn't work. I am trying with instantiate view now, but it also doesn't work (next View appear but without title and needed data)
**HomeTableViewController**
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "workoutFirstCell", for: indexPath) as! WorkoutTableCell
cell.workoutField?.setTitle(workouts[indexPath.row].workoutTitle, for: .normal)
cell.index = indexPath
cell.cellDelegate = self
return cell
} func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "workoutFirstCell", for: indexPath) as! WorkoutTableCell
cell.workoutField?.setTitle(workouts[indexPath.row].workoutTitle, for: .normal)
cell.index = indexPath
cell.cellDelegate = self
return cell
}
extension HomeTableViewController:WorkoutTableCellDelegate {
func onClickCell(index: Int) {
if let vc = storyboard?.instantiateViewController(withIdentifier: "allWorkouts") as? AllWorkoutsViewController {
vc.titleValue = workouts[index].workoutTitle
vc.tableView.reloadData()
}
}
}
Here is my cell controller
protocol WorkoutTableCellDelegate {
func onClickCell(index: Int)
}
class WorkoutTableCell: UITableViewCell {
var cellDelegate:WorkoutTableCellDelegate?
var index: IndexPath?
var item = AllWorkoutsViewController().navigationItem.title
#IBOutlet weak var workoutField: UIButton!
let user = Auth.auth().currentUser
let db = Firestore.firestore()
var models: [DataCell] = []
override func awakeFromNib() {
super.awakeFromNib()
}
#IBAction func buttonTapped(_ sender: Any) {
cellDelegate?.onClickCell(index: (index?.row)!)
}
And View Controller where I want to display navigationItemTitle with label from button in previous view
class AllWorkoutsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var titleValue: String = ""
let user = Auth.auth().currentUser
var db = Firestore.firestore()
var models: [DataCell] = []
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
navigationItem.title = titleValue
You should try this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: nil)
if segue.identifier == "youSegue" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let controller = segue.destination as! YourViewController
controller.title = workouts[indexPath.row]
}
}
}
So I'm creating a blog app, and on the home news feed collection view (imageCollection, loaded from firebase database) I have a button. This button title depends on the Category of the image. What i'm having an issue with is performing the segue in the UICollectionViewCell class. I ran the button action with the print statement, and it worked. But when i try to add performSegue, well it doesn't let me. (Use of unresolved identifier 'performSegue')
Any tips? thank you!
P.S. i'm still fairly new to swift, so if i come off a little ignorant, i apologize
My ViewController
import UIKit
import Firebase
import FirebaseDatabase
import SDWebImage
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var popImageCollection: UICollectionView!
#IBOutlet weak var imageCollection: UICollectionView!
var customImageFlowLayout = CustomImageFlowLayout()
var popImageFlowLayout = PopImagesFlowLayout()
var images = [BlogInsta]()
var popImageArray = [UIImage]()
var homePageTextArray = [NewsTextModel]()
var dbRef: DatabaseReference!
var dbPopularRef: DatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
dbRef = Database.database().reference().child("images")
dbPopularRef = Database.database().reference().child("popular")
loadDB()
loadImages()
loadText()
customImageFlowLayout = CustomImageFlowLayout()
popImageFlowLayout = PopImagesFlowLayout()
imageCollection.backgroundColor = .white
popImageCollection.backgroundColor = .white
// Do any additional setup after loading the view, typically from a nib.
}
func loadText() {
dbRef.observe(DataEventType.value, with: { (snapshot) in
if snapshot.childrenCount > 0 {
self.homePageTextArray.removeAll()
for homeText in snapshot.children.allObjects as! [DataSnapshot] {
let homeTextObject = homeText.value as? [String: AnyObject]
let titleHome = homeTextObject?["title"]
let categoryButtonText = homeTextObject?["category"]
self.imageCollection.reloadData()
let homeLabels = NewsTextModel(title: titleHome as! String?, buttonText: categoryButtonText as! String?)
self.homePageTextArray.append(homeLabels)
}
}
})
}
func loadImages() {
popImageArray.append(UIImage(named: "2")!)
popImageArray.append(UIImage(named: "3")!)
popImageArray.append(UIImage(named: "4")!)
self.popImageCollection.reloadData()
}
func loadDB() {
dbRef.observe(DataEventType.value, with: { (snapshot) in
var newImages = [BlogInsta]()
for BlogInstaSnapshot in snapshot.children {
let blogInstaObject = BlogInsta(snapshot: BlogInstaSnapshot as! DataSnapshot)
newImages.append(blogInstaObject)
}
self.images = newImages
self.imageCollection.reloadData()
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == self.imageCollection {
return images.count
} else {
return popImageArray.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == self.imageCollection {
let cell = imageCollection.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ImageCollectionViewCell
let image = images[indexPath.row]
let text: NewsTextModel
text = homePageTextArray[indexPath.row]
cell.categoryButton.setTitle(text.buttonText, for: .normal)
cell.newTitleLabel.text = text.title
cell.imageView.sd_setImage(with: URL(string: image.url), placeholderImage: UIImage(named: "1"))
return cell
} else {
let cellB = popImageCollection.dequeueReusableCell(withReuseIdentifier: "popCell", for: indexPath) as! PopularCollectionViewCell
let popPhotos = popImageArray[indexPath.row]
cellB.popularImageView.image = popPhotos
cellB.popularImageView.frame.size.width = view.frame.size.width
return cellB
}
}
}
My ImageCollectionViewCell.swift
import UIKit
import Foundation
class ImageCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var categoryButton: UIButton!
#IBOutlet weak var newTitleLabel: UILabel!
#IBOutlet weak var imageView: UIImageView!
#IBAction func categoryButtonAction(_ sender: Any) {
if categoryButton.currentTitle == "Fashion" {
print("Fashion Button Clicked")
performSegue(withIdentifier: "homeToFashion", sender: self)
}
}
override func prepareForReuse() {
super.prepareForReuse()
self.imageView.image = nil
}
}
You need a custom delegate. Do this:
protocol MyCellDelegate {
func cellWasPressed()
}
// Your cell
class ImageCollectionViewCell: UICollectionViewCell {
var delegate: MyCellDelegate?
#IBAction func categoryButtonAction(_ sender: Any) {
if categoryButton.currentTitle == "Fashion" {
print("Fashion Button Clicked")
self.delegate?.cellWasPressed()
}
}
}
// Your viewcontroller must conform to the delegate
class ViewController: MyCellDelegate {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == self.imageCollection {
let cell = imageCollection.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ImageCollectionViewCell
// set the delegate
cell.delegate = self
// ...... rest of your cellForRowAtIndexPath
}
// Still in your VC, implement the delegate method
func cellWasPressed() {
performSegue(withIdentifier: "homeToFashion", sender: self)
}
}
You should use your own delegate. It is already described here
performSegue(withIdentifier:sender:) won't work from cell because it is UIViewController metod.
also you can make use of closure
In MainVC.swift I'm capturing the tag of my custom "PlayerCell". I want to press theincreaseBtn (UIButton) which will increment the playerLbl.text (UILabel) by one but also update my model (PlayerStore.player.playerScore: Int)
Main.swift:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) as? PlayerCell {
let player = players[indexPath.row]
cell.updateUI(player: player)
cell.increaseBtn.tag = indexPath.row
cell.decreaseBtn.tag = indexPath.row
return cell
} else {
return UITableViewCell()
}
}
PlayerCell.swift
class PlayerCell: UITableViewCell {
#IBOutlet weak var playerLbl: UILabel!
#IBOutlet weak var increaseBtn: UIButton!
#IBOutlet weak var decreaseBtn: UIButton!
#IBOutlet weak var scoreLbl: UILabel!
#IBOutlet weak var cellContentView: UIView!
func updateUI(player: Player){
playerLbl.text = player.playerName
scoreLbl.text = "\(player.playerScore)"
cellContentView.backgroundColor = player.playerColor.color
}
#IBAction func increaseBtnPressed(_ sender: AnyObject) {
let tag = sender.tag
// TODO: send this tag back to MainVC?
}
I would use the delegate pattern in this case. Create a protocol that Main.swift implements, and that PlayerCell.swift uses as an optional property. So for example:
protocol PlayerIncrementor {
func increment(by: Int)
func decrement(by: Int)
}
Then use an extension on Main.swift to implement this protocol
extension Main: PlayerIncrementor {
func increment(by: int) {
//not 100% what you wanted to do with the value here, but this is where you would do something - in this case incrementing what was identified as your model
PlayerStore.player.playerScore += by
}
}
Inside of PlayerCell.swift, add a delegate property and call the delegate increment method in your #IBAction
class PlayerCell: UITableViewCell {
var delegate: PlayerIncrementor?
#IBOutlet weak var increaseBtn: UIButton!
#IBAction func increaseBtnPressed(_ sender: AnyObject) {
let tag = sender.tag
//call the delegate method with the amount you want to increment
delegate?.increment(by: tag)
}
Lastly - to make it all work, assign Main as the delegate to the PlayerCell UITableViewCell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) as? PlayerCell {
//self, in this case is Main - which now implements PlayerIncrementor
cell.delegate = self
//etc
i have collectionview that contain del button and add
cell.coupon_add.tag = indexPath.row
cell.coupon_add?.layer.setValue(id, forKey: "coupon_id")
cell.coupon_add?.layer.setValue(uID, forKey: "user_id")
cell.coupon_add?.addTarget(self, action: #selector(ViewController.addItem(_:)), forControlEvents: UIControlEvents.TouchUpInside)
func addItem(sender:UIButton) {
let point : CGPoint = sender.convertPoint(CGPointZero, toView:collectionview)
let indexPath = collectionview!.indexPathForItemAtPoint(point)
let cell = collectionview.dequeueReusableCellWithReuseIdentifier("listcell", forIndexPath: indexPath!) as! ListCell
let coupon_id : String = (sender.layer.valueForKey("coupon_id")) as! String
let user_id : String = (sender.layer.valueForKey("user_id")) as! String
if user_id == "empty" {
self.login()
}else{
print("adding item**",indexPath)
cell.coupon_add.hidden = true
cell.coupon_del.hidden = true
let buttonRow = sender.tag
print(buttonRow)
}
}
i want to hide the add button when trigger. i just get the value of the indexPath but i dont know how to hide it without refresh the collectionview
Create a custom cell
class CustomCell: UICollectionViewCell {
#IBOutlet weak var label: UILabel!
#IBOutlet weak var delButton: UIButton!
#IBOutlet weak var addButton: UIButton!
#IBAction func addTapped(sender: AnyObject) {
delButton.removeFromSuperview()
addButton.removeFromSuperview()
}
}
Typical CollectionView Controller
class ViewController: UICollectionViewController {
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10;
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CustomCell
cell.label.text = "Cell \(indexPath.row)"
return cell
}
}
And your button will gone, when you hit them