Don't Click button inside in TableView - ios

I have added one Button into tableview button is not clicked. The button is not clicked on the top of TableView. What should I do to make the button clickable? I need to make the CircleMenu button clickable. The button is now on top of tableView3. Do I need to add the button to the tableView?
override func viewDidLoad() {
super.viewDidLoad()
let button = CircleMenu(
frame: CGRect(x: view.frame.width/2 - 10, y: view.frame.height - 270, width: 50, height: 50),
normalIcon:"icon_menu",
selectedIcon:"icon_close",
buttonsCount: 3,
duration: 4,
distance: 85)
button.backgroundColor = UIColor.flatSkyBlue
button.delegate = self
button.layer.cornerRadius = button.frame.size.width / 2.0
view.addSubview(button)
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == self.tableView1 {
if !chipnumber2.text!.isEmpty {
let cell:DeviceTableViewCell2 = tableView1.dequeueReusableCell(withIdentifier: cellIdNew, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3New = itemsNew[indexPath.row]
let tap1 = UITapGestureRecognizer(target: self, action: #selector(tittleNewTapped(_:)))
let tap2 = UITapGestureRecognizer(target: self, action: #selector(tittleNewTapped2(_:)))
return cell
}
}
if tableView == self.tableView2 {
if !chipnumber.text!.isEmpty {
let cell:DeviceTableViewCell2 = tableView2.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! DeviceTableViewCell2
let deviceItem: Device3 = items[indexPath.row]
cell.backgroundColor = GradientColor(UIGradientStyle.leftToRight, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
return cell
}
}
if tableView == self.tableView3 {
if !chipnumber3.text!.isEmpty {
let cell:DeviceTableViewCell2 = tableView3.dequeueReusableCell(withIdentifier: cellIdNew2, for: indexPath) as! DeviceTableViewCell2
cell.backgroundColor = GradientColor(UIGradientStyle.leftToRight, frame: self.view.frame, colors: [UIColor.flatPowderBlueDark, UIColor.flatSand])
return cell
}
}
return UITableViewCell()
}
}

Just add a target to the button:
button.addTarget(self, action: #selector(buttonClicked(_:)), for: .touchUpInside)
And then a selector method:
#objc func buttonClicked(_ sender: UIButton) {
print("clicked!")
}
(Edit: Possible duplicate?)

Related

Can't remove view from superview on reusable tableview cell

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: EventCommentsCustom = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! EventCommentsCustom
guard let release = array[exist: indexPath.section] else { return cell }
if release.user == "condition" {
let image = UIImage()
let imageView = UIImageView(image: image)
imageView.sd_setImage(with: URL(string: "https://example.com/" + TegKeychain.get("profile_pic")!))
imageView.frame = CGRect(x: 20, y: 10, width: 50, height:50)
imageView.layer.borderWidth = 0.4
imageView.layer.masksToBounds = false
imageView.layer.borderColor = UIColor.gray.cgColor
imageView.layer.cornerRadius = 25
imageView.clipsToBounds = true
imageView.tag = 3
cell.addSubview(imageView)
let button = UIButton(frame: CGRect(x: 90, y: 10, width: 200, height: 50))
button.contentHorizontalAlignment = .left
button.setTitleColor(UIColor.lightGray, for: .normal)
button.setTitle(NSLocalizedString("Say something...", comment: ""), for: .normal)
button.addTarget(self, action: #selector(EventComments.openInput), for: .touchUpInside)
button.tag = 3
cell.addSubview(button)
} else {
if let viewWithTag = cell.viewWithTag(3) {
if viewWithTag is UIImageView {
print("DONE")
viewWithTag.removeFromSuperview()
}
}
if let viewWithTag = cell.viewWithTag(3) {
if viewWithTag is UIButton {
print("DONE")
viewWithTag.removeFromSuperview()
}
}
}
return cell
}
I am trying to remove views that I created with a tag in a reusable tableview cell.
However, I still can see UIButton and UIImageview when first reused (5. section of tableview), then It starts to remove properly
Why don't they get removed at the first reuse?
I guess that reusing in your case could mean that the image view and button get added twice for a cell. You only remove one of them though. I think you should take a different approach (like different prototype cells as #vadian stated) into consideration but for now (assuming my assumption is correct) you could try this to fix your problem:
Replace ...
if let viewWithTag = cell.viewWithTag(3) {
if viewWithTag is UIImageView {
print("DONE")
viewWithTag.removeFromSuperview()
}
}
if let viewWithTag = cell.viewWithTag(3) {
if viewWithTag is UIButton {
print("DONE")
viewWithTag.removeFromSuperview()
}
}
With ...
while let viewToRemove = cell.viewWithTag(3) {
if viewToRemove is UIImageView || viewToRemove is UIButton {
viewToRemove.removeFromSuperview()
}
}
Update -
The approach with different cell types would look something like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let release = array[exist: indexPath.section] else { return cell }
if release.user == "condition" {
let cell = tableView.dequeueReusableCell(withIdentifier: "OneIdentifier", for: indexPath) as! OneCustomCellType
// configure your cell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "AnotherIdentifier", for: indexPath) as! AnotherCustomCellType
// configure your cell
return cell
}
}

Get the indexpath from custom button in accessoryView of a UITableViewCell

I have a UISearchController with a separate UITableViewController as its searchResultsController.
class SearchResultsViewController: UITableViewController {
var fruits: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView(frame: .zero)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
#objc func addFruit(_ sender: UIButton) {
let point = tableView.convert(sender.bounds.origin, to: sender)
let indexPath = tableView.indexPathForRow(at: point)
print(indexPath?.row)
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fruits.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = fruits[indexPath.row]
cell.selectionStyle = .none
let addButton = UIButton(type: .custom)
addButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
addButton.setImage(UIImage(named: "add"), for: .normal)
addButton.contentMode = .scaleAspectFit
addButton.addTarget(self, action: #selector(addFruit(_:)), for: .touchUpInside)
addButton.sizeToFit()
cell.accessoryView = addButton
return cell
}
}
I need to show a custom button in cells that search results are shown. So I added a UIButton as the cells' accessoryView. And it looks and works fine.
Now I need to get the cell's indexPath when the user taps on this button.
I'm trying to get it like shown below.
#objc func addFruit(_ sender: UIButton) {
let point = tableView.convert(sender.bounds.origin, to: sender)
let indexPath = tableView.indexPathForRow(at: point)
}
But it keeps returning nil for every cell.
Is there any other way to get the indexPath from a custom button tap? I added a demo project here as well.
Create a custom class named SOButton and add variable of type IndexPath to it. Use this class for your add button initialisation.
//Your class will look like -
class SOButton: UIButton {
var indexPath: IndexPath?
}
//Your action will look like -
#objc func addFruit(_ sender: SOButton) {
print(sender?.indexPath.row)
}
//And in your cellForRow add
let addButton = SOButton(type: .custom)
addButton.indexPath = indexPath
Hope this helps you :)
Please update your code. you pass the UIButton sender in convert function , please pass the tableView into them
func getIndexPathByCgPoint(_ sender: UIButton) -> IndexPath? {
let point = sender.convert(sender.bounds.origin, to: tableview)
guard let indexPath = tableview.indexPathForRow(at: point) else {
return nil
}
return indexPath
}
But in case of section header it return nil.
let buttonPosition = sender.convert(CGPoint.zero, to: self.tableView)
let currentIndexPath = self.tableView.indexPathForRow(at: buttonPosition)
Try this it worked for me :)
I would suggest using this light solution: add indexPath.row to button tag:
let addButton = UIButton(type: .custom)
addButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
addButton.tag = indexPath.row
And in button action:
#objc func addFruit(_ sender: UIButton) {
print(sender.tag)
}

how to implement another level in table view?

Here I had implemented collapsible table view in which first level can be used as sections and the child class can be given as rows count and for another child class how it to be implemented in table view and I am having a expand button if I click on it need to expand and show the third level and the image is shown below libraries can anyone help me how to implement this ?
and here is my code is shown here which I had already implemented
func numberOfSections(in tableView: UITableView) -> Int {
return detailsArray.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return detailsArray[section].childern.count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView(frame: CGRect(x: 275, y: 5, width: 30, height: 35))
headerView.backgroundColor = UIColor.white
headerView.tag = section
let headerString = UILabel(frame: CGRect(x: 10, y: 10, width: tableView.frame.size.width-10, height: 30)) as UILabel
headerString.text = detailsArray[section].name
headerView .addSubview(headerString)
let btn :UIButton = UIButton(frame: CGRect(x: UIScreen.main.bounds.size.width - 35, y: 5, width: 30, height: 35))
btn.backgroundColor = UIColor.white
if (detailsArray[section].childern.count != 0){
btn.setImage(plusImage , for: .normal)
}
else {
btn.setImage(UIImage(named: ""), for: .normal)
}
if detailsArray[section].expanded == true {
btn.setImage(minusImage, for: .normal)
}
else {
btn.setImage(plusImage, for: .normal)
}
btn.tag = section
btn.addTarget(self, action: #selector(buttonTapped(sender:)), for: .touchUpInside)
headerView.addSubview(btn)
let headerTapped = UITapGestureRecognizer (target: self, action:#selector(sectionHeaderTapped(recognizer:)))
headerView .addGestureRecognizer(headerTapped)
return headerView
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
activityIndicator.stopAnimating()
activityIndicator.hidesWhenStopped = true
tableView.isHidden = false
let cell = tableView.dequeueReusableCell(withIdentifier: "categoriescell", for: indexPath) as! CategoriesTableViewCell
let obj1 = self.detailsArray[indexPath.section].childern[indexPath.row]
cell.categoryLabel?.text = obj1.name
cell.expandButton.tag = indexPath.row
cell.expandButton.setImage(plusImage, for: .normal)
return cell
}
func sectionHeaderTapped(recognizer: UITapGestureRecognizer) {
let newViewcontroller = storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.navigationController?.pushViewController(newViewcontroller, animated: true)
}
func buttonTapped(sender: UIButton) {
let section = sender.tag
detailsArray[section].expanded = !detailsArray[section].expanded
tableView.beginUpdates()
for i in 0 ..< detailsArray[section].childern.count {
tableView.reloadRows(at: [IndexPath(row: i, section: section)], with: .automatic)
}
if (detailsArray[section].childern.count != 0) {
if (sender.currentImage == plusImage){
sender.setImage(minusImage, for: .normal)
}
else {
sender.setImage(plusImage, for: .normal)
}
}
else {
sender.setImage(UIImage(named: ""), for: .normal)
}
tableView.endUpdates()
}

Label with button addTarget event not fire

I have a label in the tableview cell . label have text end of the text has a button that button represent for user like . everything is fine but problem is hitForLike not fire .button click event not fire. do i miss anything
var titleLabel : UILabel = {
var label = UILabel()
label.font = UIFont.systemFont(ofSize: 21)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
func hitForLike(_ sender : UIButton){
print("i miss you ....")
}
func titleWithLikeButton(title:String,isFavorite : Bool){
titleLabel.text = title
let button = UIButton(frame: CGRect(x: titleLabel.intrinsicContentSize.width, y: 0, width: 44, height: 44))
//setup your button here
button.setTitleColor(UIColor.red, for: UIControlState.normal)
let image = UIImage(named: "heart-empty.png")
button.setImage(image, for: UIControlState.normal)
button.addTarget(self, action: #selector(hitForLike(_:)), for: UIControlEvents.touchUpInside)
//Add the button to the text label
titleLabel.addSubview(button)
}
I think you need to enable user interaction on your label, like so:
titleLabel.isUserInteractionEnabled = true
So your entire function ends up looking like this:
func titleWithLikeButton(title:String,isFavorite : Bool){
titleLabel.text = title
titleLabel.isUserInteractionEnabled = true //enable userinteraction
let button = UIButton(frame: CGRect(x: titleLabel.intrinsicContentSize.width, y: 0, width: 44, height: 44))
//setup your button here
button.setTitleColor(UIColor.red, for: UIControlState.normal)
let image = UIImage(named: "heart-empty.png")
button.setImage(image, for: UIControlState.normal)
button.addTarget(self, action: #selector(hitForLike(_:)), for: UIControlEvents.touchUpInside)
//Add the button to the text label
titleLabel.addSubview(button)
}
Hope that helps.
You have to set your cell button target in func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell, like below:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableViewForPAC.dequeueReusableCell( withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
cell.yourButton.tag = indexpath.row
cell.yourButton.addTarget(self, action: #selector(hitForLike(_:)), for: UIControlEvents.touchUpInside)
return cell
}
func hitForLike(_ sender : UIButton){
print(sender.tag)
print("i miss you ....")
}

Programmatically added buttons target action not working in custom tableviewcell

I added programmatically two buttons in custom tableviewcell, but target action not working. What can i do to solve this problem ?(swift)
This is my code of adding buttons:
override func awakeFromNib() {
super.awakeFromNib()
func createCueButton() -> UIButton{
let button = UIButton()
button.titleLabel?.textColor = UIColor.whiteColor()
button.titleLabel?.font = UIFont.boldSystemFontOfSize(16.0)
return button
}
completeButton = createCueButton()
completeButton.setTitle("Complete", forState: UIControlState.Normal)
completeButton.backgroundColor = UIColor.greenColor()
completeButton.addTarget(self, action: "buttonPressed:", forControlEvents: .TouchUpInside)
addSubview(completeButton)
deleteButton = createCueButton()
deleteButton.setTitle("Delete", forState: .Normal)
deleteButton.backgroundColor = UIColor.redColor()
deleteButton.addTarget(self, action: "buttonPressed:", forControlEvents: .TouchUpInside)
addSubview(deleteButton)
}
func buttonPressed(sender: UIButton){
var alertView = UIAlertView();
alertView.addButtonWithTitle("OK");
alertView.title = "Alert";
alertView.message = "Button Pressed!!!";
alertView.show();
}
override func layoutSubviews() {
super.layoutSubviews()
completeButton.frame = CGRect(x: 0, y: 0, width: cuesWidth, height: bounds.size.height)
deleteButton.frame = CGRect(x: bounds.size.width - cuesWidth, y: 0, width: cuesWidth, height: bounds.size.height)
}
I preferred the answer for your question, please follow the below steps
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return 75
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let identifier = "Custom"
var cell: CustomCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? CustomCell
if cell == nil
{
tableViewCustom.registerNib(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: identifier)
cell = tableViewCustom.dequeueReusableCellWithIdentifier(identifier) as? CustomCell
}
//First Button for adding in Custom Cell
let btn = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
btn.backgroundColor = UIColor.greenColor()
btn.setTitle("Complete", forState: UIControlState.Normal)
btn.frame = CGRectMake(0, 6, 80, 40)
btn.addTarget(self, action: "completeButtonTouched:", forControlEvents: UIControlEvents.TouchUpInside)
cell.contentView.addSubview(btn)
//Second Button for adding in CustomCell
let btn2 = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
btn2.backgroundColor = UIColor.greenColor()
btn2.setTitle("Delete", forState: UIControlState.Normal)
btn2.frame = CGRectMake(180, 5, 80, 40)
btn2.addTarget(self, action: "deleteButtonTouched:", forControlEvents: UIControlEvents.TouchUpInside)
cell.contentView.addSubview(btn2)
return cell
}
func completeButtonTouched(sender:UIButton!)
{
println("Complete Button Target Action Works!!!")
}
func deleteButtonTouched(sender:UIButton!)
{
println("Delete Button Target Action Works!!!")
}
Whatever when add the button to custom cell programmatically, please apply the below code
cell.contentView.addSubview(btn)

Resources