I am a beginner to Xcode and Swift and I am currently creating an application where the user adds a person on the application and after that it right the amount of money they owe that person or that person owes him/her.
Note: I have used core data to store all the value
I actually want to change the value of a variable when switch is on and off. For instance, in the following I want the "amount" to be negative when the switch is on and positive when it is off. Also, when I try to do this and send amount variable to previous view controller I can't send the value depending on the UISwitch because it always shows positive. I am trying to find a solution to this from past 3 days therefore can you please help me? Thanks a lot in advance
Owe ViewController
import UIKit
class NewOweTableViewController: UIViewController {
#IBOutlet weak var titleTextField: UITextField!
#IBOutlet weak var locationTextField: UITextField!
#IBOutlet weak var amountTextField: UITextField!
#IBOutlet weak var datePicker: UIDatePicker!
let context = (UIApplication.shared.delegate as!
AppDelegate).persistentContainer.viewContext
var owe: Owe?
var dataInfo: [Owe] = []
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.viewWithTag(1)?.isHidden = true
let saveBTN = UIBarButtonItem(barButtonSystemItem:UIBarButtonSystemItem.save, target:self,
action: #selector(saveButtonTapped(_:)))
let deleteBTN = UIBarButtonItem(barButtonSystemItem:UIBarButtonSystemItem.trash, target:self,
action: #selector(deleteButtonTapped(_:)))
self.navigationItem.rightBarButtonItems = [saveBTN, deleteBTN]
if !dataInfo.isEmpty {
titleTextField.text = dataInfo[0].name
amountTextField.text = (NSString(format: "%.2f", (dataInfo[0].amount) as CVarArg) as String)
locationTextField.text = dataInfo[0].location
datePicker.date = dataInfo[0].date!
}
}
#objc func saveButtonTapped(_ sender: UIButton){
if !dataInfo.isEmpty{
let data = dataInfo[0]
data.name = titleTextField.text
data.amount = Double(amountTextField.text!)!
data.location = locationTextField.text
data.date = datePicker.date
}
else if titleTextField.text == "" || amountTextField.text == "" || locationTextField.text == "" {
return
}
else{
let data = Owe(context: context)
data.name = titleTextField.text
data.amount = Double(amountTextField.text!)!
data.location = locationTextField.text
data.date = datePicker.date
}
do {
try context.save()
navigationController?.popViewController(animated: true)
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
#objc func deleteButtonTapped(_ sender: UIButton){
if !dataInfo.isEmpty{
let data = dataInfo[0]
context.delete(data)
do {
try context.save()
navigationController?.popViewController(animated: true)
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
#IBAction func oweSwitch(_ sender: UISwitch) {
if sender.isOn {
owe?.amount = (owe?.amount)! * (-1)
amountTextField.textColor = UIColor.green
} else {
owe?.amount = (owe?.amount)! * (1)
amountTextField.textColor = UIColor.red
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Previous View Controller
import UIKit
class PersonDetailTableViewController: UITableViewController {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var totalLabel: UILabel?
var person: People?
var owe: Owe?
#IBOutlet var personTable: UITableView!
var dataInfo: [Owe] = []
var selectedObject: [Owe] = []
var balanceAmount = "Balance: "
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (dataInfo.count)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = personTable
.dequeueReusableCell(withIdentifier: "detailsCell", for: indexPath)
cell.textLabel?.text = dataInfo[indexPath.row].name
cell.detailTextLabel?.text = "₹ \(dataInfo[indexPath.row].amount)"
if dataInfo[indexPath.row].amount < 0 {
cell.detailTextLabel?.textColor = UIColor.red
} else {
cell.detailTextLabel?.textColor = UIColor.green
}
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
selectedObject = [dataInfo[indexPath.row]]
performSegue(withIdentifier: "addOweDetails", sender: nil)
tableView.deselectRow(at: indexPath, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
getData()
personTable.dataSource = self
addTotalToNav()
print(dataInfo as Any)
}
// MARK: - Table view data source
func addTotalToNav() -> Void {
if let navigationBar = self.navigationController?.navigationBar {
let totalFrame = CGRect(x: 10, y: 0, width: navigationBar.frame.width/2, height: navigationBar.frame.height)
totalLabel = UILabel(frame: totalFrame)
totalLabel?.text = balanceAmount
totalLabel?.tag = 1
totalLabel?.font = UIFont.boldSystemFont(ofSize: 14)
totalLabel?.textColor = UIColor.red
// navigationBar.large = totalLabel?.text
self.title = totalLabel?.text
}
}
func getData() -> Void {
do{
dataInfo = try context.fetch(Owe.fetchRequest())
var total:Double = 0.00
for i in 0 ..< dataInfo.count {
total += dataInfo[i].amount as! Double
}
balanceAmount = "Balance: ₹" + (NSString(format: "%.2f", total as CVarArg) as String)
}
catch{
print("Fetching Failed")
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! NewOweTableViewController
vc.dataInfo = selectedObject
selectedObject.removeAll()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
getData()
personTable.reloadData()
if (self.navigationController?.navigationBar.viewWithTag(1)?.isHidden == true){
self.navigationController?.navigationBar.viewWithTag(1)?.removeFromSuperview()
addTotalToNav()
}
}
}
Core Data for owe
import UIKit
import CoreData
#objc(Owe)
public class Owe: NSManagedObject {
var date: Date? {
get{
return rawDate as Date?
}
set {
rawDate = newValue as NSDate?
}
}
convenience init?(name: String?, location: String?, amount: Double, date: Date?) {
let appDelegate = UIApplication.shared.delegate as? AppDelegate
guard let context = appDelegate?.persistentContainer.viewContext
else {
return nil
}
self.init(entity: Owe.entity(), insertInto: context)
self.name = name
self.location = location
self.amount = amount
self.date = date
}
}
Hi there and welcome to the Swift Community!
If I understand correctly, you are trying to propagates updates backwards from NewOweTableViewController to PersonDetailTableViewController. If that is the case, an easy way to achieve this with your MVC architecture is by passing a closure to NewOweTableViewController when you initialize it in PersonDetailTableViewController.
In order to do so,
Update NewOweTableViewController and add a closure property.
class NewOweTableViewController: UIViewController {
// ...
var switchValueUpdate: ((Bool) -> ())?
// ...
}
Make sure you call this closure inside your #IBAction that you link to your switch in NewOweTableViewController
#IBAction func oweSwitch(_ sender: UISwitch) {
if sender.isOn {
owe?.amount = (owe?.amount)! * (-1)
amountTextField.textColor = UIColor.green
} else {
owe?.amount = (owe?.amount)! * (1)
amountTextField.textColor = UIColor.red
}
switchValueUpdate?(sender.isOn)
}
update PersonDetailTableViewController to set the closure
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! NewOweTableViewController
vc.dataInfo = selectedObject
selectedObject.removeAll()
vc.switchValueUpdate = { (isOn) in
// Here you go, update PersonDetailTableViewController to reflect changes related to the switch!
}
}
That's it! Let me know if you have any question on that code, hope it helps!
Related
I am trying to get the inputted text from recipeName, servingsNumber, prepTime and cookTime to save to fb.
I know this is close to where I need to be. I am need some help with my save function. I need to assign the textField.text in sendToFirebase() I am able to print out the inputted text into the console and I was able to get it to save a document to FB but the entry was null. What am I missing? I feel like it is here in my code:
import UIKit
import Firebase
class AddRecipeViewController: UIViewController {
#IBOutlet weak var table: UITableView!
#IBOutlet weak var saveButton: UIBarButtonItem!
let db = Firestore.firestore()
var id = UUID().uuidString
var data = [RecipeData]()
let user = Auth.auth().currentUser?.email
var objRecipe = RecipeData.init()
override func viewDidLoad() {
super.viewDidLoad()
table.delegate = self
table.dataSource = self
navigationItem.hidesBackButton = true
let newBackButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelPressed))
self.navigationItem.leftBarButtonItem = newBackButton
table.register(UINib(nibName: "RecipeNameCell", bundle: nil), forCellReuseIdentifier: "recipeName")
table.register(UINib(nibName: "ServingSizeTableViewCell", bundle: nil), forCellReuseIdentifier: "servings")
table.register(UINib(nibName: "PrepTimeTableViewCell", bundle: nil), forCellReuseIdentifier: "prep")
table.register(UINib(nibName: "CookTimeTableViewCell", bundle: nil), forCellReuseIdentifier: "cook")
}
func sendToFirebase() {
do {
let recipeName = objRecipe.recipeName
let servings = objRecipe.servingsNumber
let prep = objRecipe.prepTime
let cook = objRecipe.cookTime
let user = Auth.auth().currentUser?.email
let id = objRecipe.id
let data = try JSONEncoder().encode(objRecipe)
let dictionary = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] ?? [:]
db.collection("Recipe").document(objRecipe.id).setData(dictionary)
}
catch {
print(error)
}
}
#objc func cancelPressed(sender: UIBarButtonItem) {
navigationController?.popViewController(animated: true)
dismiss(animated: true, completion: nil)
}
#IBAction func savePressed(_ sender: UIBarButtonItem) {
sendToFirebase()
}
}
extension AddRecipeViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = table.dequeueReusableCell(withIdentifier: "recipeName", for: indexPath) as! RecipeNameCell
cell.textField.delegate = self
cell.textField.tag = indexPath.row
return cell
}
else if indexPath.row == 1 {
let cell = table.dequeueReusableCell(withIdentifier: "servings", for: indexPath) as! ServingSizeTableViewCell
cell.textField.delegate = self
cell.textField.tag = indexPath.row
return cell
}
else if indexPath.row == 2 {
let cell = table.dequeueReusableCell(withIdentifier: "prep", for: indexPath) as! PrepTimeTableViewCell
cell.textField.delegate = self
cell.textField.tag = indexPath.row
return cell
}
else if indexPath.row == 3{
let cell = table.dequeueReusableCell(withIdentifier: "cook", for: indexPath) as! CookTimeTableViewCell
cell.textField.delegate = self
cell.textField.tag = indexPath.row
return cell
}
else {
let cell = table.dequeueReusableCell(withIdentifier: "recipeName", for: indexPath) as! RecipeNameCell
return cell
}
}
}
extension AddRecipeViewController: UITextFieldDelegate {
func textFieldDidEndEditing(_ textField: UITextField) {
switch textField.tag {
case 0:
let recipeName = textField.text!
print(recipeName)
objRecipe.recipeName = textField.text!
// sendToFirebase() // Send to firebase
case 1:
let servingSize = textField.text!
print(servingSize)
objRecipe.servingsNumber = textField.text!
// sendToFirebase() // Send to firebase
case 2:
let prepTime = textField.text!
print(prepTime)
objRecipe.prepTime = textField.text!
// sendToFirebase() // Send to firebase
case 3:
let cookTime = textField.text!
print(cookTime)
objRecipe.cookTime = textField.text!
// sendToFirebase() // Send to firebase
default: break
}
}
}
struct RecipeData: Codable {
var user: String?
var recipeName: String?
var ingredientsText: String?
var directionsText: String?
var servingsNumber: String?
var prepTime: String?
var cookTime: String?
var image: String?
let id = UUID().uuidString
}
class RecipeNameCell: UITableViewCell {
#IBOutlet weak var textField: UITextField!
var id = UUID().uuidString
let db = Firestore.firestore()
var name: String?
override func awakeFromNib() {
super.awakeFromNib()
textField.placeholder = "Recipe Name..."
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
func saveData(text: String) {
if let recipeName = recipeNameTextField.text,
let addedIngredients = ingredientsTextField.text,
let directionsText = directionsTextField.text,
let servingsNum = numServingLabel.text,
let image = imageView.image,
let user = Auth.auth().currentUser?.email {
let newRecipeRef = db.collection(D.FStore.collectionName).document(id)
newRecipeRef.setData([
D.FStore.recipeTextField: recipeName,
D.FStore.ingredientsText: addedIngredients,
D.FStore.directionsText: directionsText,
D.FStore.numberServings: servingsNum,
D.FStore.userField: user,
D.FStore.id: id,
D.FStore.image: image,
]) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("Document added with ID:\(newRecipeRef)")
}
}
}
}
import UIKit
import Firebase
class HomeScreenViewController: UIViewController {
#IBOutlet weak var table: UITableView!
#IBOutlet weak var logout: UIBarButtonItem!
#IBOutlet weak var add: UIBarButtonItem!
let db = Firestore.firestore()
var data = [RecipeData]()
var recipeNamed: String?
override func viewDidLoad() {
super.viewDidLoad()
table.delegate = self
table.dataSource = self
navigationItem.hidesBackButton = true
table.register(UINib(nibName: "RecipeCell", bundle: nil), forCellReuseIdentifier: "cell")
}
func loadRecipeNames() {
db.collection("Recipe")
.addSnapshotListener { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let data = document.data()
if let user = data["User"] as? String,
let recipeNameLabels = data["Recipe Name"] as? String,
let prep = data["Prep Time"] as? String,
let cook = data["Cook Time"] as? String,
let servings = data["Servings"] as? String
{
let newRecipe = RecipeData(user: user, recipeName: recipeNameLabels, servingsNumber: servings, prepTime: prep, cookTime: cook)
self.data.append(newRecipe)
}
DispatchQueue.main.async {
self.table.reloadData()
}
}
}
}
}
#IBAction func logoutPress(_ sender: UIBarButtonItem) {
do {
try Auth.auth().signOut()
navigationController?.popToRootViewController(animated: true)
} catch let signOutError as NSError {
print("Error signing out: %#", signOutError)
}
}
#IBAction func addRecipePressed(_ sender: UIBarButtonItem) {
performSegue(withIdentifier: "add", sender: self)
}
}
extension HomeScreenViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let data = data[indexPath.row]
let cell = table.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! RecipeCell
cell.recipeNameLabel.text = data.recipeName
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "DetailSegue", sender: self)
}
}
You need to fire the sendToFirebase() function:
extension AddRecipeViewController: UITextFieldDelegate {
func textFieldDidEndEditing(_ textField: UITextField) {
switch textField.tag {
case 0:
let recipeName = textField.text!
print(recipeName)
objRecipe.recipeName = textField.text!
sendToFirebase() // Send to firebase
case 1:
let servingSize = textField.text!
print(servingSize)
objRecipe.servingsNumber = textField.text!
sendToFirebase()
case 2:
let prepTime = textField.text!
print(prepTime)
objRecipe.prepTime = textField.text!
sendToFirebase()
case 3:
let cookTime = textField.text!
print(cookTime)
objRecipe.cookTime = textField.text!
sendToFirebase()
default: break
}
}
}
sendToFirebase() function:
func sendToFirebase() {
let recipeName = objRecipe.recipeName
let servings = objRecipe.servingsNumber
let prep = objRecipe.prepTime
let cook = objRecipe.cookTime
let user = Auth.auth().currentUser?.email
let newRecipeRef = db.collection("Recipe").document(objRecipe.id)
newRecipeRef.setData([
"Recipe Name" : recipeName ?? "Empty",
"Serving #" : servings ?? "Empty",
"Prep Time" : prep ?? "Empty",
"Cook Time" : cook ?? "Empty",
"User" : user ?? "No email provided",
])
{ err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("Document added with ID:\(newRecipeRef)")
}
}
}
enter image description hereimport UIKit
class MyCircleViewPresenter: BaseViewPresenter {
typealias V = MyCircleViewDelegate
var mView: V?
func getMyCircle(url: String){
mView?.onNetworkCallStarted("please_wait".localized())
AlamofireService.getSession()
.request(url, method: .get).validate()
.responseJSON { (response) in
self.mView?.onNetworkCallEnded()
switch(response.result){
case .success(_):
guard let decodedObj = response.decode(objectType: MyCircleResponse.self) else {
self.mView?.myCircleDidReceived(response: nil)
return
}
self.mView?.myCircleDidReceived(response: decodedObj)
break
case .failure(let error):
self.mView?.handleError(httpSatusCode: response.response?.statusCode, errorData: response.data, error: error)
break
}
}
}
}
//
// MyCircleViewController.swift
import UIKit
struct MyCircleSection {
let number: String
let recharges: [SingeRecharge]
var isOpened: Bool = false
struct SingeRecharge {
let amount: String
let rechargeType: Int
let create_at: String
}
}
class MyCircleViewController: BaseViewController {
// Out let >>>>>
#IBOutlet weak var card_current_month: CardView!
#IBOutlet weak var card_last_3o_days: CardView!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var lb_my_circle_total: RegularLabel!
var sections = [MyCircleSection]()
var mPresenter = MyCircleViewPresenter()
var historyType = Constants.HistoryType.CURRENT_MONTH
override func onViewDidLoaded() {
mPresenter.setViewDelegate(mView: self)
// Set Up table View
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.rowHeight = 62
// Swipe
let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleGesture))
swipeLeft.direction = .left
self.view!.addGestureRecognizer(swipeLeft)
setupClickListener()
card_current_month.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
card_current_month.shadowColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
card_last_3o_days.shadowColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
}
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(menuDidTapped), name: .MENU_DID_TAPPED, object: nil)
if(historyType == Constants.HistoryType.CURRENT_MONTH){ // Curent Month
card_current_month.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
mPresenter.getMyCircle(url: APIs.MY_CIRCLE + "/\(historyType)")
}else{ // Last 30 days
card_current_month.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
mPresenter.getMyCircle(url: APIs.MY_CIRCLE + "/\(historyType)")
}
lb_my_circle_total.text = "..."
tableView.isHidden = true
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: .MENU_DID_TAPPED, object: nil)
}
#objc func menuDidTapped(_ notification: NSNotification){
guard let menuType = notification.object as? MenuType else {
return
}
print("Menu Type: Reward >>> \(menuType)")
switch menuType {
case .PROFILE:
performSegue(withIdentifier: ProfileViewController.className, sender: self)
break
case .REFER_SC_APP:
AppUtils.shared.referThisApp(fromVc: self)
break
case .TRANSACTION_AND_STATEMENT:
performSegue(withIdentifier: TransactionViewController.className, sender: self)
break
case .FAQ:
performSegue(withIdentifier: FaqViewController.className, sender: self)
break
case .SUPPORT:
performSegue(withIdentifier: SupportViewController.className, sender: self)
break
case .SETTINGS:
performSegue(withIdentifier: SettingsViewController.className, sender: self)
break
case .LOGOUT:
showLogoutDialog()
break
}
}
func setupClickListener(){
card_current_month.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tabClickListener(_:))))
card_last_3o_days.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tabClickListener(_:))))
}
#objc func tabClickListener(_ gesture: UIGestureRecognizer){
guard let tag = gesture.view?.tag else { return }
if(tag == 1){ // Curent Month
if(historyType != Constants.HistoryType.CURRENT_MONTH){
historyType = Constants.HistoryType.CURRENT_MONTH
lb_my_circle_total.text = "..."
tableView.isHidden = true
card_current_month.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
mPresenter.getMyCircle(url: APIs.MY_CIRCLE + "/\(Constants.HistoryType.CURRENT_MONTH)")
}
}else{ // Last 30 days
if(historyType != Constants.HistoryType.LAST_30_DAYS){
historyType = Constants.HistoryType.LAST_30_DAYS
lb_my_circle_total.text = "..."
tableView.isHidden = true
card_current_month.borderColor = UIColor(hexaRGB: Color.GREY_LIGHT)!
card_last_3o_days.borderColor = UIColor(hexaRGB: Color.PRIMARY)!
mPresenter.getMyCircle(url: APIs.MY_CIRCLE + "/\(Constants.HistoryType.LAST_30_DAYS)")
}
}
}
#objc func handleGesture(gesture: UISwipeGestureRecognizer) -> Void {
if gesture.direction == UISwipeGestureRecognizer.Direction.left {
NotificationCenter.default.post(name: .USER_DID_SWIPE_TO_LEFT, object: nil)
}
}
}
extension MyCircleViewController: MyCircleViewDelegate {
func myCircleDidReceived(response: MyCircleResponse?) {
if(response == nil){
lb_my_circle_total.text = "0"
showErrorDialog(title: "No data found!", msg: nil, titleFullRed: true)
}else{
lb_my_circle_total.text = "\(response!.data.count)"
// Format Data for Table View >>>
if (!sections.isEmpty) {sections.removeAll()}
for (number , recharges) in response!.data {
var rechargeHistories = [MyCircleSection.SingeRecharge]()
for singleRecharge in recharges {
rechargeHistories.append(MyCircleSection.SingeRecharge(amount: singleRecharge.amount, rechargeType : singleRecharge.rechargeType, create_at: singleRecharge.createdAt))
}
sections.append(MyCircleSection(number: number, recharges: rechargeHistories))
}
// Reload Table view data >>>
self.tableView.reloadData()
self.tableView.isHidden = false
}
}
}
//// Table View Delegate >>>
extension MyCircleViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let section = sections[section]
return section.isOpened ? section.recharges.count + 1 : 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if(indexPath.row == 0){
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCircleHeaderCell.className) as? MyCircleHeaderCell else {
return UITableViewCell()
}
let section = sections[indexPath.section]
cell.lb_circle_number.text = section.recharges.isEmpty ? section.number : section.number + " (\(section.recharges.count))"
cell.img_arrow.image = section.isOpened ? UIImage(named: "ic-arrow-up") : UIImage(named: "ic-down-arrow")
return cell
}else{
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCircleRowCell.className) as? MyCircleRowCell else {
return UITableViewCell()
}
let data = sections[indexPath.section].recharges[indexPath.row - 1]
cell.lb_amount.text = Constants.TAKA_UNICODE + "\(data.amount)"
let formattedDateTime = DateUtils.shared.convertUTCtimeToLocale(dateToFormat: data.create_at)
cell.lb_date.text = formattedDateTime.0
cell.lb_time.text = formattedDateTime.1
switch "\(data.rechargeType)" {
case Constants.RechargeType.EASY_LOAD:
cell.lb_type.text = "Easyload"
case Constants.RechargeType.BUNDLE:
cell.lb_type.text = "Bundle"
case Constants.RechargeType.INTERNET:
cell.lb_type.text = "Internet"
case Constants.RechargeType.VOICE:
cell.lb_type.text = "Voice"
case Constants.RechargeType.VAS:
cell.lb_type.text = "Vas"
default:
cell.lb_type.text = ""
break
}
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if(indexPath.row == 0){
sections[indexPath.section].isOpened = !sections[indexPath.section].isOpened
tableView.reloadSections([indexPath.section], with: .none)
}
}
}
// Qeustion Cell >>>>
class MyCircleHeaderCell: UITableViewCell{
#IBOutlet weak var lb_circle_number : RegularLabel!
#IBOutlet weak var img_arrow: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
self.selectionStyle = .none
}
}
// Answer Cell >>>
class MyCircleRowCell: UITableViewCell {
#IBOutlet weak var lb_date : PreRegularLight!
#IBOutlet weak var lb_time : PreRegularLight!
#IBOutlet weak var lb_amount: PreRegularBoldLabel!
#IBOutlet weak var lb_type: PreRegularLight!
override func awakeFromNib() {
super.awakeFromNib()
self.selectionStyle = .none
}
}
a JSON response is never sorted in some way. it always come in different orders, and are decoded as such. i suggest you yourself sort the array on date or something to get a consistent order of the objects.
I'm working on study project of social network. Stuck on the stage of deleting user comments from Firebase database. To delete a specific comment I need to know the comment Id, but I do not understand how to access it. I'm really appreciate any help on this!
Example of Firebase database:
CommentViewController:
class CommentViewController: UIViewController {
#IBOutlet weak var sendButton: UIButton!
#IBOutlet weak var commentTextField: UITextField!
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var constraintToBottom: NSLayoutConstraint!
var postId: String!
var comments = [Comment]()
var users = [User]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
title = "Comment"
tableView.estimatedRowHeight = 77
tableView.rowHeight = UITableView.automaticDimension
empty()
handleTextField()
loadComments()
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
#objc func keyboardWillShow(_ notification: NSNotification) {
let keyboardFrame = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
UIView.animate(withDuration: 0.3) {
self.constraintToBottom.constant = keyboardFrame!.height
self.view.layoutIfNeeded()
}
}
#objc func keyboardWillHide(_ notification: NSNotification) {
UIView.animate(withDuration: 0.3) {
self.constraintToBottom.constant = 0
self.view.layoutIfNeeded()
}
}
var comment: Comment?
func loadComments() {
Api.Post_Comment.REF_POST_COMMENTS.child(self.postId).observe(.childAdded, with: {
snapshot in
Api.Comment.observeComments(withPostId: snapshot.key, completion: {
comment in
self.fetchUser(uid: comment.uid!, completed: {
self.comments.append(comment)
self.tableView.reloadData()
})
})
})
}
func fetchUser(uid: String, completed: #escaping() -> Void ) {
Api.User.observeUser(withId: uid, completion: {
user in
self.users.append(user)
completed()
})
}
func handleTextField() {
commentTextField.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControl.Event.editingChanged)
}
#objc func textFieldDidChange() {
if let commentText = commentTextField.text, !commentText.isEmpty {
sendButton.setTitleColor(UIColor.black, for: UIControl.State.normal)
sendButton.isEnabled = true
return
}
sendButton.setTitleColor(UIColor.lightGray, for: UIControl.State.normal)
sendButton.isEnabled = false
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.tabBar.isHidden = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.tabBarController?.tabBar.isHidden = false
}
#IBAction func sendButton_TouchUpInside(_ sender: Any) {
let commentsReference = Api.Comment.REF_COMMENTS
let newCommentId = commentsReference.childByAutoId().key!
let newCommentReference = commentsReference.child(newCommentId)
guard let currentUser = Api.User.CURRENT_USER else {
return
}
let currentUserId = currentUser.uid
newCommentReference.setValue(["uid": currentUserId, "commentText": commentTextField.text!], withCompletionBlock: {
(error, ref) in
if error != nil {
ProgressHUD.showError(error!.localizedDescription)
return
}
let postCommentRef = Api.Post_Comment.REF_POST_COMMENTS.child(self.postId).child(newCommentId)
postCommentRef.setValue(true, withCompletionBlock: { (error, ref) in
if error != nil {
ProgressHUD.showError(error!.localizedDescription)
return
}
})
self.empty()
self.view.endEditing(true)
})
}
func empty() {
self.commentTextField.text = ""
sendButton.setTitleColor(UIColor.lightGray, for: UIControl.State.normal)
sendButton.isEnabled = false
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Comment_ProfileSegue" {
let profileVC = segue.destination as! ProfileUserViewController
let userId = sender as! String
profileVC.userId = userId
}
}
extension CommentViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return comments.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentTableViewCell
let comment = comments[indexPath.row]
let user = users[indexPath.row]
cell.comment = comment
cell.user = user
cell.delegate = self
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == .delete) {
}
}
CommentTableViewCell:
class CommentTableViewCell: UITableViewCell {
#IBOutlet weak var profileImageView: UIImageView!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var commentLabel: UILabel!
var delegate: CommentTableViewCellDelegate?
var comment: Comment? {
didSet {
updateView()
}
}
var user: User? {
didSet {
setupUserInfo()
}
}
func updateView() {
commentLabel.text = comment?.commentText
}
func setupUserInfo() {
nameLabel.text = user?.username
if let photoUrlString = user?.profileImageUrl {
let photoUrl = URL(string: photoUrlString)
profileImageView.sd_setImage(with: photoUrl, placeholderImage: UIImage(named: "photo_placeholder"))
}
}
override func awakeFromNib() {
super.awakeFromNib()
nameLabel.text = ""
commentLabel.text = ""
let tapGestureForNameLabel = UITapGestureRecognizer(target: self, action: #selector(self.nameLabel_TouchUpInside))
nameLabel.addGestureRecognizer(tapGestureForNameLabel)
nameLabel.isUserInteractionEnabled = true
}
#objc func nameLabel_TouchUpInside() {
if let id = user?.id {
delegate?.goToProfileUserVC(userId: id)
}
}
override func prepareForReuse() {
super.prepareForReuse()
profileImageView.image = UIImage(named: "placeholderImg")
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
Comment Api
class CommentApi {
var REF_COMMENTS = Database.database().reference().child("comments")
func observeComments(withPostId id: String, completion: #escaping (Comment) -> Void) {
REF_COMMENTS.child(id).observeSingleEvent(of: .value, with: {
snapshot in
if let dict = snapshot.value as? [String: Any] {
let newComment = Comment.transformComment(dict: dict, key: snapshot.key)
completion(newComment)
}
})
}
func observeComment(withId id: String, completion: #escaping (Comment) -> Void) {
REF_COMMENTS.child(id).observeSingleEvent(of: DataEventType.value, with: {
snapshot in
if let dict = snapshot.value as? [String: Any] {
let comment = Comment.transformComment(dict: dict, key: snapshot.key)
completion(comment)
}
})
}
Comment Model:
class Comment {
var commentText: String?
var uid: String?
var id: String?}
extension Comment {
static func transformComment(dict: [String: Any], key: String) -> Comment {
let comment = Comment()
comment.id = key
comment.commentText = dict["commentText"] as? String
comment.uid = dict["uid"] as? String
return comment
}
Speaking at a high level, your tableView is backed by a dataSource, typically an array, which is the source for the content displayed in the tableView.
var userCommentArray = [UserComment]()
you should be loading data from Firebase and storing that data in the array as UserComment objects
class UserComment {
var firebaseKey = ""
var commentText = ""
var uid = ""
}
the firebase_key property is the key to the node in Firebase, shown as -MH_xxxx in the screenshot and then the commentText and uid are is the child data of that node.
The indexes of the elements in the array match what's being shown in the tableView, so row0 matches the array index 0, row 1 matches the array index 1 etc.
When the user deletes row 1, you know that's index 1 in the array. read the object, get it's firebaseKey and then delete it from firebase, updating the array accordingly and then reloading your UI.
See my answer to your Other Question for details on that process.
I have data coming from Firebase and when the data is loaded I either want the an image to be hidden or shown based on some logic in my custom cell. It works perfectly fine when the data isn't being filtered but the second I type in the search bar or change the scope bar to a different index the image doesn't behave right.
For example: Index 0 should not have the image and index 1 should. Which is how it displays when it first loads. However, when I search I know the previous index 1 (now index 0) should still have it's image but it doesn't. BUT if I click to go to the detail controller it brings me to the right page. It's like it loads all the accurate info but does the logic on the original index 0. I would love some help as I have been searching for an answer FOREVER. Thank you in advance!
tableViewCell:
class SearchTalentCell: UITableViewCell {
#IBOutlet weak var userProfileImage: UIImageView!
#IBOutlet weak var talentUserName: UILabel!
#IBOutlet weak var selectedImg: UIImageView!
#IBOutlet weak var inviteSentImg: UIImageView!
var prospectRef: FIRDatabaseReference!
//#IBOutlet weak var radioButton: UIButton!
var currentTalent: UserType!
//var delegate: SearchCellDelegate?
func setTalent(talent: UserType) {
currentTalent = talent
currentTalent.userKey = talent.userKey
}
override func awakeFromNib() {
super.awakeFromNib()
let tap = UITapGestureRecognizer(target: self, action: #selector(selectTapped))
tap.numberOfTapsRequired = 1
selectedImg.addGestureRecognizer(tap)
selectedImg.isUserInteractionEnabled = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
/*#IBAction func radioButtonTapped(_ sender: Any) {
delegate?.didTapRadioButton(userKey: currntTalent.userKey, searchSelected: currntTalent.searchSelected!.rawValue, radioButton: radioButton)
}*/
func configureCell(user: UserType, img: UIImage? = nil) {
prospectRef = Cast.REF_PRE_PRODUCTION_CASTING_POSITION.child(ProjectDetailVC.currentProject).child(FIRDataCast.prospect.rawValue).child(CastingDetailVC.positionName).child(user.userKey)
//setTalent(talent: user)
self.talentUserName.text = "\(user.firstName) \(user.lastName)"
//self.inviteSentImg.image = UIImage(named: "inviteSent")
//user.adjustSearchSelected(talent: user, radioButton: radioButton)
prospectRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let _ = snapshot.value as? NSNull {
self.inviteSentImg.isHidden = true
print("**Image hidden")
} else {
self.inviteSentImg.image = UIImage(named: "inviteSent")
print("**Image shown")
}
})
//Image Caching
if img != nil {
self.userProfileImage.image = img
} else {
if let imageURL = user.profileImage {
let ref = FIRStorage.storage().reference(forURL: imageURL)
ref.data(withMaxSize: 2 * 1024 * 1024, completion: { (data, error) in
if error != nil {
print("ZACK: Unable to download image from Firebase Storage")
} else {
print("ZACK: Image downloaded from Firebase Storage")
if let imgData = data {
if let img = UIImage(data: imgData) {
self.userProfileImage.image = img
SearchTalentVC.userProfileImageCache.setObject(img, forKey: imageURL as NSString)
}
}
}
})
}
}
}
Viewcontroller:
class SearchTalentVC: UITableViewController/*, SearchCellDelegate*/ {
var searchingRole = [Cast]()
var unfilteredTalent = [UserType]()
var filteredTalent = [UserType]()
var selectedTalent = [UserType]()
var matchingTalentUserKeys = [String]()
var isFiltered = false
var prospectRef: FIRDatabaseReference!
static var userProfileImageCache: NSCache<NSString, UIImage> = NSCache()
let searchController = UISearchController(searchResultsController: nil)
//#IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search Talent"
searchController.searchBar.barStyle = .black
navigationItem.searchController = searchController
definesPresentationContext = true
searchController.searchBar.scopeButtonTitles = ["All", "Role Specific"]
searchController.searchBar.tintColor = UIColor.white
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
getTalentProfiles()
}
func searchBarIsEmpty() -> Bool {
return searchController.searchBar.text?.isEmpty ?? true
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredTalent = unfilteredTalent.filter({ (talent : UserType) -> Bool in
let doesTalentMatch = (scope == "All") || doesUserKeyMatch(talent: talent.userKey)
if searchBarIsEmpty() {
return doesTalentMatch
} else {
let fullName = "\(talent.firstName) \(talent.lastName)"
return doesTalentMatch && fullName.lowercased().contains(searchText.lowercased())
}
})
tableView.reloadData()
}
func doesUserKeyMatch(talent: String) -> Bool {
self.filterRoleFeature()
return matchingTalentUserKeys.contains(talent)
}
func isSearching() -> Bool {
let searchBarScopeIsFiltering = searchController.searchBar.selectedScopeButtonIndex != 0
return searchController.isActive && (!searchBarIsEmpty() || searchBarScopeIsFiltering)
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if isSearching() {
return filteredTalent.count
} else {
return unfilteredTalent.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "userSearchCell"
if let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? SearchTalentCell {
var talent: UserType
if isSearching() {
print("we are searching")
talent = self.filteredTalent[indexPath.row]
print("indexPath: \(indexPath.row)")
} else {
print("we are not searching")
talent = self.unfilteredTalent[indexPath.row]
}
if let imageURL = talent.profileImage {
if let img = SearchTalentVC.userProfileImageCache.object(forKey: imageURL as NSString) {
cell.configureCell(user: talent, img: img)
} else {
cell.configureCell(user: talent)
//cell.delegate = self
}
return cell
} else {
cell.configureCell(user: talent)
//cell.delegate = self
return SearchTalentCell()
}
} else {
return SearchTalentCell()
}
}
extension SearchTalentVC: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
let searchBar = searchController.searchBar
let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
filterContentForSearchText(searchController.searchBar.text!, scope: scope)
self.tableView.reloadData()
}
}
extension SearchTalentVC: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}
}
If you are hidding image in If part then you should put logic of showing image also in else block. See if this solve your problem.
if let _ = snapshot.value as? NSNull {
self.inviteSentImg.isHidden = true
print("**Image hidden")
} else {
self.inviteSentImg.isHidden = false
self.inviteSentImg.image = UIImage(named: "inviteSent")
print("**Image shown")
}
I have one screen like the following picture:
I uploaded list with student name by using custom cell as you are seeing and I want when click on save button save the status of student in array , I initialized array with 0 for all student at the first time and when the status of switch is enabled then this value at the clicked cell index converted to 1 but I couldn't make that when the click action happened on switch this is only now happening when click on the cell ( row ) how I can do the same thing when only change the status of switch to update the array without click on complete row at table
Code of main view :
import UIKit
class teacherAttendanceVC: UIViewController , UITableViewDataSource,UITableViewDelegate {
#IBOutlet weak var studentlistTable: UITableView!
#IBOutlet weak var loadIndicator: UIActivityIndicatorView!
var username:String?
var classID: String?
var branchID: String?
var normal_id = [String]()
var student_name = [String]()
var student_attendance = [String]()
//Sent Data
var n_id = ""
var stu_name = ""
#IBAction func backButton(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil )
}
override func viewDidLoad() {
super.viewDidLoad()
studentlistTable.delegate = self
studentlistTable.dataSource = self
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
username = prefs.objectForKey("user")as! String
classID = prefs.objectForKey("ClassID")as! String
branchID = prefs.objectForKey("BranchID")as! String
self.loadIndicator.startAnimating()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
self.loadList()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.loadIndicator.stopAnimating()
self.studentlistTable.reloadData()
})
});
}
override func viewDidAppear(animated: Bool) {
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return normal_id.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//This method to define each cell at Table View
let cell = self.studentlistTable.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! teacherAttendanceCell
cell.studentNameLabel.text = student_name[indexPath.row]
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Get Cell Label
let currentCell = studentlistTable.cellForRowAtIndexPath(indexPath) as! teacherAttendanceCell!
student_attendance[indexPath.row] = currentCell.status
}
#IBAction func saveButton(sender: AnyObject) {
print(student_attendance) // this only to ensure from the final array before sending to server
}
func loadList()
{
var normallink = "myurl"
normallink = normallink + "?classid=" + self.classID! + "&branchid=" + self.branchID!
print(normallink)
var studentParentURL:NSURL = NSURL (string: normallink)!
let data = NSData(contentsOfURL: studentParentURL)!
do {
let json = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
if let alldata = json["data"] as? [[String: AnyObject]] {
for onedata in alldata {
if let no_id = onedata["id"] as? String {
normal_id.append(no_id)
}
if let s_name = onedata["studentName"] as? String {
student_name.append(s_name)
}
}
}
} catch {
print("Error Serializing JSON: \(error)")
}
if(normal_id.count != 0)
{
for i in 1...self.normal_id.count
{
self.student_attendance.append("0")
}
}
print(normal_id.count)
print(student_name.count)
}
}
Cell Code :
class teacherAttendanceCell: UITableViewCell {
#IBOutlet weak var studentNameLabel: UILabel!
#IBOutlet weak var attendSwitch: UISwitch!
var status:String = ""
override func awakeFromNib() {
super.awakeFromNib()
if(attendSwitch.on)
{
status = "1"
print("ON")
}
else{
status = "0"
print("OFF")
}
attendSwitch.addTarget(self, action: "stateChanged:", forControlEvents: UIControlEvents.ValueChanged)
}
func stateChanged(switchState: UISwitch) {
if switchState.on {
status = "1"
print("ON")
} else {
status = "0"
print("OFF")
}
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
#IBAction func attendSwitchChanged(sender: AnyObject) {
}
}
Updated:
Main View Controller:
import UIKit
class teacherAttendanceVC: UIViewController , UITableViewDataSource,UITableViewDelegate,CellInfoDelegate {
#IBOutlet weak var studentlistTable: UITableView!
#IBOutlet weak var loadIndicator: UIActivityIndicatorView!
var username:String?
var classID: String?
var branchID: String?
var normal_id = [String]()
var student_name = [String]()
var student_attendance = [String]()
//Sent Data
var n_id = ""
var stu_name = ""
#IBAction func backButton(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil )
}
override func viewDidLoad() {
super.viewDidLoad()
studentlistTable.delegate = self
studentlistTable.dataSource = self
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
username = prefs.objectForKey("user")as! String
classID = prefs.objectForKey("ClassID")as! String
branchID = prefs.objectForKey("BranchID")as! String
self.loadIndicator.startAnimating()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
self.loadList()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.loadIndicator.stopAnimating()
self.studentlistTable.reloadData()
})
});
}
override func viewDidAppear(animated: Bool) {
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return normal_id.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//This method to define each cell at Table View
let cell = self.studentlistTable.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! teacherAttendanceCell
cell.delegate = self
cell.studentNameLabel.text = student_name[indexPath.row]
student_attendance[indexPath.row] = cell.status
//print(student_attendance.count)
//let currentCell = studentlistTable.cellForRowAtIndexPath(indexPath) as! teacherAttendanceCell!
// student_attendance.append(cell.status)
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Get Cell Label
// let currentCell = studentlistTable.cellForRowAtIndexPath(indexPath) as! teacherAttendanceCell!
// student_attendance[indexPath.row] = currentCell.status
//print("OK Status here!" + String(student_attendance.count))
}
#IBAction func saveButton(sender: AnyObject) {
print(student_attendance)
}
func loadList()
{
var normallink = "mylinkhere"
normallink = normallink + "?classid=" + self.classID! + "&branchid=" + self.branchID!
print(normallink)
var studentParentURL:NSURL = NSURL (string: normallink)!
let data = NSData(contentsOfURL: studentParentURL)!
do {
let json = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments)
if let alldata = json["data"] as? [[String: AnyObject]] {
for onedata in alldata {
if let no_id = onedata["id"] as? String {
normal_id.append(no_id)
}
if let s_name = onedata["studentName"] as? String {
student_name.append(s_name)
}
}
}
} catch {
print("Error Serializing JSON: \(error)")
}
if(normal_id.count != 0)
{
for i in 1...self.normal_id.count
{
self.student_attendance.append("0")
}
}
print(normal_id.count)
print(student_name.count)
}
func processThatNumber(theStatus: String) {
print("out : \(theStatus)")
}
}
protocol CellInfoDelegate {
func processThatNumber(theStatus: String)
}
Cell View Controller:
import UIKit
class teacherAttendanceCell: UITableViewCell{
#IBOutlet weak var studentNameLabel: UILabel!
#IBOutlet weak var attendSwitch: UISwitch!
var status:String = ""
var delegate: CellInfoDelegate?
override func awakeFromNib() {
super.awakeFromNib()
if(attendSwitch.on)
{
status = "1"
print("ON")
}
else{
status = "0"
print("OFF")
}
attendSwitch.addTarget(self, action: "stateChanged:", forControlEvents: UIControlEvents.ValueChanged)
}
func stateChanged(switchState: UISwitch) {
if switchState.on {
status = "1"
print("ON")
} else {
status = "0"
print("OFF")
}
if let delegate = self.delegate {
delegate.processThatNumber(self.status)
}
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
#IBAction func attendSwitchChanged(sender: AnyObject) {
}
}
There are few ways to do this: using closure or delegate, but I preferred to use delegate.
Create a delegate for your teacherAttendanceCell cell like in this answer https://stackoverflow.com/a/25792213/2739795
Make you teacherAttendanceVC conforms the delegate
Each time when cellForRowAtIndexPath calls set cell.delegate = self. Also return the cell into your delegate method
Call method from delegate insidestateChanged
And when delegate method calls you can get an index if switched cell
tableView.indexPathForCell(cellFromParam)