How to get table view index when click to radio button in swift 4? - ios

I am doing project in swift 4. I created radiobutton class in tableview cell. I want to get cell index when click to which radio button. Please help me.
Edit: I just added my entire code. I could not solve my problem. All of the codes are as follows. I created a radio button class and gave it a radio button feature. I tried to integrate the radio button in the tableview and get the index of the cell when the button is clicked as below, but it gave libc++abi.dylib: terminating with uncaught exception of type NSException error.
import UIKit
class TVCIsGuvenligi: UITableViewCell {
lazy var radioButtonGroup: [RadioButton] = {
return [
btnRadioEvet,
btnRadioHayir,
]
}()
#IBOutlet var lblSoru: UILabel!
#IBOutlet var lblSoruAyrinti: UILabel!
#IBOutlet var lblEvet: UILabel!
#IBOutlet var lblHayır: UILabel!
#IBOutlet var btnRadioEvet: RadioButton!
#IBAction func btnRadioEvet(_ sender: RadioButton)
{
let indexPath = IndexPath.init(row: sender.tag, section: 0)
updateRadioButton(sender)
print("index \(indexPath)")
}
#IBOutlet var btnRadioHayir: RadioButton!
#IBAction func btnRadioHayir(_ sender: RadioButton)
{
let indexPath = IndexPath.init(row: sender.tag, section: 0)
updateRadioButton(sender)
print("index \(indexPath)")
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func updateRadioButton(_ sender: RadioButton){
radioButtonGroup.forEach { $0.isSelected = false }
sender.isSelected = !sender.isSelected
}
}
ViewController.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIs", for: indexPath) as! TVCIsGuvenligi
cell.lblSoru.text = myTitle[indexPath.row]
cell.lblSoruAyrinti.text = myTitle[indexPath.row]
cell.btnRadioEvet.tag = (indexPath.row)
cell.btnRadioEvet.addTarget(self, action: #selector(getter: cell.btnRadioEvet), for: UIControlEvents.touchUpInside)
print("current cell tag \(cell.btnRadioEvet.tag)")
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//getting the index path of selected row
let indexPath = tableView.indexPathForSelectedRow
//getting the current cell from the index path
let currentCell = tableView.cellForRow(at: indexPath!)! as! TVCIsGuvenligi
//getting the text of that cell.
let currentItem = currentCell.lblSoru.text
print("current item \(currentItem)")
}

use,
currentCell.radioButton.tag = indexPath.row
And use this tag to get index on the radio button click

Related

Change button title in section of tableview on specific row

I have view controller in which there are multiple section of tableview. In section 0 I have multiple row . Each row having button named as Add Comments when I click on button it pushes me to other view controller having text field when i wrote something and press done button then through delegate I passes textfield data and set it in button title. But problem is my button present in all row changes value. I want only selected row in section changes its button title. below is my code of first viewcontroller
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 {
if(indexPath.section == 0)
{
let indetifier = "MyTabTableViewCell"
let cell = tableView.dequeueReusableCell(withIdentifier: indetifier, for: indexPath) as! MyTabTableViewCell
cell.addCommentsButton.setTitle(addCommentsValueStore, for: UIControl.State.normal)
}
return cell
}
extension MyTabViewController: AddCommentsDelegate{
func passAddComments(instruction: String) {
addCommentsValueStore = instruction
print(addCommentsValueStore)
}
}
}
below is code of second 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) {
self.navigationController?.popViewController(animated: true)
}
#IBAction func DoneActionClick(_ sender: Any) {
let dataToBeSent = addCommentsTextField.text
self.passAddCommentsDelegate?.passAddComments(instruction: dataToBeSent!)
self.navigationController?.popViewController(animated: true)
}
}
by using tag on the cell button, you can fix your problem.
on your cellForRowAt delegate method, put this line:
cell.addCommentsButton.tag = indexPath.item
now you know exactly which button did select, then you can use this tag to specify which row in your tableView should change its title.
your implementation has some problems:
first of all, the addCommentsValueStore have to be an array of strings.
var addCommentsValueStore: [String] = []
then tell the delegate to show the right title:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: MyTabTableViewCell!
if (indexPath.section == 0) {
cell = tableView.dequeueReusableCell(withIdentifier: "MyTabTableViewCell", for: indexPath) as! MyTabTableViewCell
cell.tag = indexPath.item
cell.addCommentsButton.setTitle(addCommentsValueStore[indexPath.item], for: UIControl.State.normal)
}
return cell
}
the AddCommentsDelegate should return the index too:
protocol AddCommentsDelegate {
func passAddComments(instruction: String, atIndex: Int)
}
then every time you want to pass comment to another viewController, you should pass the index too.
by using this index, you will specify where you should change the row button title.
#UIBotton func DoneActionClick(_ sender: UIButton) {
let dataToBeSent = addCommentsTextField[sender.tag].text
self.passAddCommentsDelegate?.passAddComments(instruction: dataToBeSent!, atIndexPath: sender.tag)
self.navigationController?.popViewController(animated: true)
}

How to use one tableview's button to automatically select the other tableview's button all

I'm making a tableview that allows users to select items, primary is the main item, and each primary item contains a secondary list, I created a custom cell and also inserted the other tableview inside, as shown in the picture link below.
Form picture
Here's my ViewController.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, PrimaryDelegate {
#IBOutlet weak var tableView: UITableView!
//This is my data
var cardList = Card(userName: "Kevin", primaryList: [Card.Primary(primaryName: "Card1", secondaryList: [Card.Primary.Secondary(secondaryName: "Card1-1")]),Card.Primary(primaryName: "Card2", secondaryList: [Card.Primary.Secondary(secondaryName: "Card2-1"),Card.Primary.Secondary(secondaryName: "Card2-2")])])
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
}
#IBAction func enterAction(_ sender: Any) {
//I hope here can print the result
//How should I get the result from primaryList and secondaryList in Custom Cell ?
print(cardList)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cardList.primaryList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath) as! CustomTableViewCell
cell.primaryLabel.text = cardList.primaryList[indexPath.row].primaryName
cell.secondaryList = cardList.primaryList[indexPath.row].secondaryList
cell.primaryIndex = indexPath.row
cell.primaryDelegate = self
return cell
}
func primaryIndex(index:Int) {
//I use delegate to get index, but how to tell which secondaryList needs to be selected all?
print("primaryIndex\(index)")
}
}
Here's my Custom Cell, it includes the other tableview, that's why I feel complicated.
class CustomTableViewCell: UITableViewCell,UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var primaryBtn: UIButton!
#IBOutlet weak var secondaryBtn: UIButton!
#IBOutlet weak var primaryLabel: UILabel!
#IBOutlet weak var secondaryLabel: UILabel!
#IBOutlet weak var secondaryTableView: UITableView!
#IBOutlet weak var secondaryHeight: NSLayoutConstraint!
var primaryIndex:Int?
var primaryDelegate:PrimaryDelegate?
var secondaryList:[Card.Primary.Secondary]!{
didSet{
secondaryTableView.delegate = self
secondaryTableView.dataSource = self
secondaryTableView.reloadData()
secondaryHeight.constant = secondaryTableView.contentSize.height
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return secondaryList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomTableViewCell", for: indexPath) as! CustomTableViewCell
cell.secondaryLabel.text = secondaryList[indexPath.row].secondaryName
return cell
}
#IBAction func primaryBtnAction(_ sender: UIButton) {
sender.isSelected = !primaryBtn.isSelected
primaryDelegate?.primaryIndex(index: primaryIndex!)
}
#IBAction func secondaryBtnAction(_ sender: UIButton) {
sender.isSelected = !secondaryBtn.isSelected
}
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
I hope it can be...
1.When the user selects the primary item, it can automatically help me select all the secondary items. However, the primary item can only be selected "one", and when the user selects the next primary item, the previous one needs to be canceled including all secondary items.
2.When the user press enterAction, it can print the data that user have chosen.I need to know what if user not choose primary, How many secondary list's item is selected.
I mean like result is Card1-1 and Card2-1, they only choose item in secondary list.
How should I tell custom cell's tableview to select all when I choose primary item, and how did custom cell know which primary is selected and needs to reload Data?
If need further information, please let me know, this selection rule make me really confused.Thanks
You can use this at your primaryBtnAction :
if sender.isSelected{
for section in 0..<tableView.numberOfSections {
for row in 0..<tableView.numberOfRows(inSection: section) {
tableView.selectRow(at: IndexPath(row: row, section: section), animated: false, scrollPosition: .none)
}
}
} else { //Deselect statement
tableView.deselectRow(at: IndexPath(row: row, section: section), animated: false)
}
Hope it helps...

When scroll table view content change

i have custom table view cell that having rating stars. i'm using https://github.com/hsousa/HCSStarRatingView for rating View.
there is my code for table view and cell view.
class RatingTableViewCell: UITableViewCell {
var value : CGFloat = 0.0
#IBOutlet weak var starRatingView: HCSStarRatingView!
#IBOutlet weak var titleLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
initStarRatingView()
starRatingView.addTarget(self, action: #selector(DidChangeValue(_:)), for: .valueChanged)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
private func initStarRatingView() {
var scalingTransform : CGAffineTransform!
scalingTransform = CGAffineTransform(scaleX: -1, y: 1);
starRatingView.transform = scalingTransform
starRatingView.emptyStarImage = #imageLiteral(resourceName: "strokStar")
starRatingView.halfStarImage = #imageLiteral(resourceName: "halfStar")
starRatingView.filledStarImage = #imageLiteral(resourceName: "fillStar")
starRatingView.allowsHalfStars = true
}
#IBAction func DidChangeValue(_ sender: HCSStarRatingView) {
self.value = sender.value
}
class RatingViewController: CustomViewController,UITableViewDelegate,UITableViewDataSource {
var values : [CGFloat] = [0.5,0.0,0.0,0.0,0.0,0.0,0.0]
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "RatingTableViewCell", for: indexPath) as! RatingTableViewCell
values[indexPath.row] = cell.value
cell.starRatingView.value = values[indexPath.row]
return cell
}
//MARK: _Table data source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
values.count
}
}
there is a problem when i scroll table view. dequeue Reusable Cell data is wrong. how can update value data for each cell?
The problem is that you are storing the value in the cell. Take a look at those two lines:
let cell = tableView.dequeueReusableCell(withIdentifier: "RatingTableViewCell", for: indexPath) as! RatingTableViewCell
values[indexPath.row] = cell.value
You dequeue a cell and assign it's value to values[indexPath.row]. The problems that you are noticing when scrolling are caused by the fact that the reused cell was previously used for a different indexPath, which means that their value (that you assign to values[indexPath.row]) is meant for its previous indexPath.
To fix that, I would advise getting rid of the value variable in RatingTableViewCell. Instead, define a protocol RatingTableViewCellDelegate that will be used to inform the RatingViewController about the new value.

how implement a button in customized UITableViewCell in Swift 3?

I tried to use this solution but is not working.
what I want i s a button in my customized cell that knows data from the array that is used from the tableview (later I'll apply it to CoreData), for example, print the value of the array that generated the tableview.
but I cannot understand how to do it
I have a customized cell class, where I tried to use both a button action or a outlet button (with tags):
import UIKit
class MyTableViewCell: UITableViewCell {
#IBOutlet weak var myCellImage: UIImageView!
#IBOutlet weak var myCellLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
and a ViewController where is my tableview with an extension
extension ViewController {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return comicsArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = myTableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyTableViewCell
cell.myCellLabel.text = String(indexPath.row)
cell.myCellButton.tag = indexPath.row
cell.myCellButton.addTarget(self, action: Selector("logAction:"), for: .touchUpInside)
return cell
}
func logAction(sender: UIButton) {
let titleString = self.comicsArray[sender.tag]
let firstActivityItem = "\(titleString)"
let activityVC = UIActivityViewController(activityItems: [firstActivityItem], applicationActivities: nil)
self.present(activityVC, animated: true, completion: nil)
}
}
EDIT:
solved with help of abdullahselek by adding in subclasses cell:
public var dataFromTableView : String!
and implementing:
#IBAction func myCellButtonTapped(_ sender: UIButton) {
guard dataFromTableView != nil else {return}
print("pushed \(dataFromTableView!)")
}
and in cellForRowAt :
cell.data = comicsArray[indexPath.row]
Add a dictionary or object model property to your custom tableviewcell like
public var data: Dictionary!
And set this data property
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
cell.data = comicsArray[indexPath.row]
}
Then you button can reach data with in your tableviewcell

Create reference of custom cell in function and update Label in Swift

I've been trying to use the custom cell in function when button is clicked. and update a label in that specific row using the function.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = myTableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CardCell
cell.startcount.tag = indexPath.row
cell.startcount.addTarget(self, action: "startcount:", forControlEvents:UIControlEvents.TouchUpInside)
}
here is the function I'm using
func startcount(sender: AnyObject){
// create a reference of CardCell
// update the counter like cell.textcount.text = "\(counter)"
// in the specific row
}
My custom cell class :
import UIKit
class CardCell: UITableViewCell {
#IBOutlet weak var textcount: UILabel!
#IBOutlet weak var startcount: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
func startcount(sender: AnyObject){
let button = sender as UIButton
let indexPath = NSIndexPath(forRow:button.tag inSection:0)
let cell = tableView.cellForRowAtIndexPath(indexPath) as CardCell
// update cell
}
For Swift 4 and above
func startCount(sender : AnyObject) {
let button = sender as! UIButton
let indexPath = IndexPath(row:button.tag ,section:0)
let cell = tableView.cellForRow(at: indexPath) as! CardCell
// update cell
}

Resources