Post

Replies

Boosts

Views

Activity

Reply to How do I get the value of a selected row in a table view?
This is the actual file from my app. Can you help me please? When I run it, line 71 is throwing an error that it found nil while unwrapping a nil value.import UIKit var myRoster: [String]? struct DataToPass { var playerData: String = "" } @available(iOS 11.0, *) class Top_30_Quarterbacks: UIViewController, UITableViewDelegate, UITableViewDataSource { var objectsArray: [String] = ["1. Patrick Mahomes, KC", "2. Deshaun Watson, HOU", "3. Aaron Rodgers, GB", "4. Matt Ryan, ATL", "5. Baker Mayfield, CLE", "6. Carson Wentz, PHI", "7. Jared Goff, LAR", "8. Cam Newton, CAR", "9. Andrew Luck, IND", "10. Drew Brees, NO", "11. Ben Roethlisberger, PIT", "12. Dak Prescott, DAL", "13. Russell Wilson, SEA", "14. Tom Brady, NE", "15. Lamar Jackson, BAL", "16. Mitchell Trubisky, CHI", "17. Jameis Winston, TB", "18. Philip Rivers, LAC", "19. Kirk Cousins, MIN", "20. Derek Carr, OAK", "21. Sam Darnold, NYJ", "22. Josh Allen, BUF", "23. Matthew Stafford, DET", "24. Marcus Mariota, TEN", "25. Jimmy Garoppolo, SF", "26. Andy Dalton, CIN", "27. Eli Manning, NYG", "28. Nick Foles, JAC", "29. Joe Flacco, DEN", "30. Ryan Fitzpatrick, MIA" ] func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return objectsArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath) cell.textLabel?.text = objectsArray[indexPath.row] cell.textLabel?.adjustsFontSizeToFitWidth = true cell.textLabel?.font = UIFont.systemFont(ofSize: 22) return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { top30QuarterbacksTable.deselectRow(at: indexPath, animated: true) } func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let player: String = objectsArray[indexPath.row] let add = UIContextualAction(style: .normal, title: "Add") { (contextualAction, view, actionPerformed: @escaping (Bool) -> Void) in let alert = UIAlertController(title: "Add Player", message: "Are you sure you want to add '\(player)' to your roster?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: { (alertAction) in actionPerformed(false) })) alert.addAction(UIAlertAction(title: "Yes", style: .destructive, handler: { (alertAction) in self.addPlayer(index: indexPath.row) })) self.present(alert, animated: true) } add.backgroundColor = .systemGreen let taken = UIContextualAction(style: .normal, title: "Taken") { (contextualAction, view, actionPerformed: @escaping (Bool) -> Void) in let alert = UIAlertController(title: "Player Taken", message: "Are you sure you want to mark '\(player)' as not available?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: { (alertAction) in actionPerformed(false) })) alert.addAction(UIAlertAction(title: "Yes", style: .destructive, handler: { (alertAction) in })) self.present(alert, animated: true) } taken.backgroundColor = .systemRed return UISwipeActionsConfiguration(actions: [taken, add]) } func addPlayer(index: Int) { let index = top30QuarterbacksTable.indexPathForSelectedRow! if let cell = top30QuarterbacksTable.cellForRow(at: index) { let string = objectsArray[0] cell.textLabel?.text = string if myRoster!.isEmpty { myRoster?.insert(string, at: 0) } else { myRoster?.append(string) } } } func markAsTaken() { } @IBOutlet weak var top30QuarterbacksTable: UITableView! @IBOutlet var view1: UIView! @IBOutlet weak var view2: UIView! @IBOutlet weak var label: UILabel! override func viewDidLoad() { super.viewDidLoad() } }
Dec ’19
Reply to How do I iterate through an array to add 1 to the variable every time the loop runs?
Yes, it worked by + 1 to indexPath.row in cellForRowAt.So I don't have to run a for loop to add 1 to the row every time?I used numPick() as a function to hold the integer for the number of row.This is what my table view looks like:func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath) cell.textLabel?.text = "\(numPick())" + (myRoster?[indexPath.row])! cell.textLabel?.adjustsFontSizeToFitWidth = true cell.textLabel?.font = UIFont.systemFont(ofSize: 22) return cell }
Dec ’19
Reply to How do I save a table view?
import UIKit @available(iOS 11.0, *) class Top_30_Quarterbacks: UIViewController, UITableViewDelegate, UITableViewDataSource { var objectsArray: [String] = ["Patrick Mahomes, KC", "Deshaun Watson, HOU", "Aaron Rodgers, GB", "Matt Ryan, ATL", "Baker Mayfield, CLE", "Carson Wentz, PHI", "Jared Goff, LAR", "Cam Newton, CAR", "Andrew Luck, IND", "Drew Brees, NO", "Ben Roethlisberger, PIT", "Dak Prescott, DAL", "Russell Wilson, SEA", "Tom Brady, NE", "Lamar Jackson, BAL", "Mitchell Trubisky, CHI", "Jameis Winston, TB", "Philip Rivers, LAC", "Kirk Cousins, MIN", "Derek Carr, OAK", "Sam Darnold, NYJ", "Josh Allen, BUF", "Matthew Stafford, DET", "Marcus Mariota, TEN", "Jimmy Garoppolo, SF", "Andy Dalton, CIN", "Eli Manning, NYG", "Nick Foles, JAC", "Joe Flacco, DEN", "Ryan Fitzpatrick, MIA" ] func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return objectsArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath) cell.textLabel?.text = "\(indexPath.row+1). " + objectsArray[indexPath.row] cell.textLabel?.adjustsFontSizeToFitWidth = true cell.textLabel?.font = UIFont.systemFont(ofSize: 22) return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { top30QuarterbacksTable.deselectRow(at: indexPath, animated: true) } func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { let cell = self.top30QuarterbacksTable.cellForRow(at: indexPath) let str: String = (cell?.textLabel!.text)! let player: String = objectsArray[indexPath.row] if cell?.textLabel?.attributedText == strikeThroughText(str) { strikeThroughTextBool = true } else { strikeThroughTextBool = false } if strikeThroughTextBool == false { let add = UIContextualAction(style: .normal, title: "Add") { (contextualAction, view, actionPerformed: @escaping (Bool) -> Void) in let alert = UIAlertController(title: "Add Player", message: "Are you sure you want to add '\(player)' to your roster?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: { (alertAction) in actionPerformed(false) })) alert.addAction(UIAlertAction(title: "Yes", style: .destructive, handler: { (alertAction) in self.addPlayer(index: indexPath) cell?.textLabel?.attributedText = strikeThroughText(str) let okayAlert = UIAlertController(title: "Player Added!", message: "You added '\(player)' to your roster?", preferredStyle: .alert) okayAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (alertAction) in actionPerformed(true) })) self.present(okayAlert, animated: true) cell?.backgroundColor = .systemGray3 })) self.present(alert, animated: true) } add.backgroundColor = .systemGreen let taken = UIContextualAction(style: .normal, title: "Taken") { (contextualAction, view, actionPerformed: @escaping (Bool) -> Void) in let alert = UIAlertController(title: "Player Taken", message: "Are you sure you want to mark '\(player)' as taken and not available?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: { (alertAction) in actionPerformed(false) })) alert.addAction(UIAlertAction(title: "Yes", style: .destructive, handler: { (alertAction) in self.markAsTaken(index: indexPath) cell?.textLabel?.attributedText = strikeThroughText(str) let okayAlert = UIAlertController(title: "Taken Player", message: "You marked '\(player)' as taken and not available!", preferredStyle: .alert) okayAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (alertAction) in actionPerformed(true) })) self.present(okayAlert, animated: true) cell?.backgroundColor = .systemGray2 })) self.present(alert, animated: true) } taken.backgroundColor = .systemRed let config = UISwipeActionsConfiguration(actions: [taken, add]) config.performsFirstActionWithFullSwipe = false return config } else { let undo = UIContextualAction(style: .normal, title: "Undo") { (contextualAction, view, actionPerformed: @escaping (Bool) -> Void) in let alert = UIAlertController(title: "Undo", message: "Are you sure you want undo the action for '\(player)'?", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "No", style: .cancel, handler: { (alertAction) in actionPerformed(false) })) alert.addAction(UIAlertAction(title: "Yes", style: .destructive, handler: { (alertAction) in self.removePlayer(index: indexPath) cell?.textLabel?.attributedText = noStrikeThroughText(str) let okayAlert = UIAlertController(title: "Action Undone", message: "The previous action for '\(player)' has been undone!", preferredStyle: .alert) okayAlert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (alertAction) in actionPerformed(true) })) self.present(okayAlert, animated: true) cell?.backgroundColor = .none })) self.present(alert, animated: true) } undo.backgroundColor = .systemBlue let config = UISwipeActionsConfiguration(actions: [undo]) config.performsFirstActionWithFullSwipe = false return config } } func addPlayer(index: IndexPath) { let cell = top30QuarterbacksTable.cellForRow(at: index) let str: String = objectsArray[index.row] cell?.accessoryType = UITableViewCell.AccessoryType.checkmark if myRoster == [""] { myRoster?.insert(str, at: 0) myRoster?.remove(at: 1) } else { myRoster?.append(str) } if draftOrder == [""] { draftOrder?.insert(str, at: 0) draftOrder?.remove(at: 1) } else { draftOrder?.append(str) } } func removePlayer(index: IndexPath) { let cell = top30QuarterbacksTable.cellForRow(at: index) let str: [String] = [objectsArray[index.row]] cell?.accessoryType = UITableViewCell.AccessoryType.none myRoster?.removeAll(where: { str.contains($0) }) draftOrder?.removeAll(where: { str.contains($0) }) } func markAsTaken(index: IndexPath) { _ = top30QuarterbacksTable.cellForRow(at: index) let str: String = objectsArray[index.row] if draftOrder == [""] { draftOrder?.insert(str, at: 0) draftOrder?.remove(at: 1) } else { draftOrder?.append(str) } } @IBOutlet weak var top30QuarterbacksTable: UITableView! @IBOutlet var view1: UIView! @IBOutlet weak var view2: UIView! @IBOutlet weak var label: UILabel! override func viewDidLoad() { super.viewDidLoad() } }
Dec ’19
Reply to How do I save a table view?
objectsArray is set. Nothing is appended to it. When I add, it adds the contents to another array named myRoster. In this table view, strikeThroughText adds a line through the cell text at indexPath if the cell data is added to myRoster. It also adds a checkmark to the cell and changes the color of the cell. If the cell text has a line through it, that means that the data in the cell is already added to myRoster or added to draftOrder. In this case, if there is a line through the cell text, when I swipe there is an 'undo' button which deletes that player from myRoster or draftOrder, deletes the line going through the text, and deletes the checkmark. The app is working perfectly except that I cannot save the view if I change views and that when I add the cell data with a swipe and either 'add' button or 'taken' button, when I scroll down the table view, there is a line through the text, a checkmark, and the cell color is changed in every 15th table view row.
Dec ’19
Reply to How do I save a table view?
Hello, The reason why myRoster == [""] and not [] is because the app was crashing and finding nil. I had tomyRoster?.remove(at: 1) to remove the [""] after the string was inserted.For some reason now, I changed it to an emty array and removed line 3 and now it works.I don't use myRoster in this tableView because I want it accessed by other classes. For instance, I have other files that have classes such as:Top_80_RunningBacks and Top_80_WideReceivers.The information isn't lost when I return to the view. All that is lost is:- strikeThroughText- cell?accessoryType- cell?backgroundColorAnother thing, when I scroll down and then scroll back up to the changed cell, the changes are lost.
Dec ’19
Reply to How do I save a table view?
I have been trying to do what you proposed. I think I almost got it.1. I setup a global structstruct Data { var num: Int = 0 var name: String = "" var strikeThrough: Bool = false var color: Bool = false var accessory: Bool = false } var objectsArray = [Data]()2. I setup a global functionfunc quarterBacks() { objectsArray = [ Data(num: 1, name: "Patrick Mahomes, KC", strikeThrough: false, color: false, accessory: false), Data(num: 2, name: "Deshaun Watson, HOU", strikeThrough: false, color: false, accessory: false), Data(num: 3, name: "Aaron Rodgers, GB", strikeThrough: false, color: false, accessory: false), Data(num: 4, name: "Matt Ryan, ATL", strikeThrough: false, color: false, accessory: false), Data(num: 5, name: "Baker Mayfield, CLE", strikeThrough: false, color: false, accessory: false), Data(num: 6, name: "Carson Wentz, PHI", strikeThrough: false, color: false, accessory: false), Data(num: 7, name: "Jared Goff, LAR", strikeThrough: false, color: false, accessory: false), Data(num: 8, name: "Cam Newton, CAR", strikeThrough: false, color: false, accessory: false), Data(num: 9, name: "Andrew Luck, IND", strikeThrough: false, color: false, accessory: false), Data(num: 10, name: "Drew Brees, NO", strikeThrough: false, color: false, accessory: false), Data(num: 11, name: "Ben Roethlisberger, PIT", strikeThrough: false, color: false, accessory: false), Data(num: 12, name: "Dak Prescott, DAL", strikeThrough: false, color: false, accessory: false), Data(num: 13, name: "Russell Wilson, SEA", strikeThrough: false, color: false, accessory: false), Data(num: 14, name: "Tom Brady, NE", strikeThrough: false, color: false, accessory: false), Data(num: 15, name: "Lamar Jackson, BAL", strikeThrough: false, color: false, accessory: false), Data(num: 16, name: "Mitchell Trubisky, CHI", strikeThrough: false, color: false, accessory: false), Data(num: 17, name: "Jameis Winston, TB", strikeThrough: false, color: false, accessory: false), Data(num: 18, name: "Philip Rivers, LAC", strikeThrough: false, color: false, accessory: false), Data(num: 19, name: "Kirk Cousins, MIN", strikeThrough: false, color: false, accessory: false), Data(num: 20, name: "Derek Carr, OAK", strikeThrough: false, color: false, accessory: false), Data(num: 21, name: "Sam Darnold, NYJ", strikeThrough: false, color: false, accessory: false), Data(num: 22, name: "Josh Allen, BUF", strikeThrough: false, color: false, accessory: false), Data(num: 23, name: "Matthew Stafford, DET", strikeThrough: false, color: false, accessory: false), Data(num: 24, name: "Marcus Mariota, TEN", strikeThrough: false, color: false, accessory: false), Data(num: 25, name: "Jimmy Garoppolo, SF", strikeThrough: false, color: false, accessory: false), Data(num: 26, name: "Andy Dalton, CIN", strikeThrough: false, color: false, accessory: false), Data(num: 27, name: "Eli Manning, NYG", strikeThrough: false, color: false, accessory: false), Data(num: 28, name: "Nick Foles, JAC", strikeThrough: false, color: false, accessory: false), Data(num: 29, name: "Joe Flacco, DEN", strikeThrough: false, color: false, accessory: false), Data(num: 30, name: "Ryan Fitzpatrick, MIA", strikeThrough: false, color: false, accessory: false) ] }3. I call quarterbacks() in viewDidLoad()override func viewDidLoad() { super.viewDidLoad() quarterBacks() }4. I set the structs data in my three functions addPlayer(index: IndexPath), removePlayer(index: IndexPath), and markAsTaken(index: IndexPath)func addPlayer(index: IndexPath) { _ = top30QuarterbacksTable.cellForRow(at: index) let str: String = objectsArray[index.row].name objectsArray[index.row].strikeThrough = true objectsArray[index.row].accessory = true objectsArray[index.row].color = true if myRoster == [] { myRoster?.insert(str, at: 0) } else { myRoster?.append(str) } if draftOrder == [] { draftOrder?.insert(str, at: 0) } else { draftOrder?.append(str) } top30QuarterbacksTable.reloadData() } func removePlayer(index: IndexPath) { _ = top30QuarterbacksTable.cellForRow(at: index) let str: [String] = [objectsArray[index.row].name] objectsArray[index.row].strikeThrough = false objectsArray[index.row].color = false objectsArray[index.row].accessory = false myRoster?.removeAll(where: { str.contains($0) }) draftOrder?.removeAll(where: { str.contains($0) }) top30QuarterbacksTable.reloadData() } func markAsTaken(index: IndexPath) { _ = top30QuarterbacksTable.cellForRow(at: index) let str: String = objectsArray[index.row].name objectsArray[index.row].strikeThrough = true objectsArray[index.row].color = true objectsArray[index.row].accessory = false if draftOrder == [] { draftOrder?.insert(str, at: 0) } else { draftOrder?.append(str) } top30QuarterbacksTable.reloadData() }5. I setup cellForRowAt with if statementsfunc tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) let num = objectsArray[indexPath.row].num let name = objectsArray[indexPath.row].name cell.textLabel?.text = "\(num). \(name)" cell.textLabel?.adjustsFontSizeToFitWidth = true cell.textLabel?.font = UIFont.systemFont(ofSize: 22) if objectsArray[indexPath.row].strikeThrough == false && objectsArray[indexPath.row].accessory == false && objectsArray[indexPath.row].color == false { cell.textLabel?.text = "\(num). \(name)" cell.textLabel?.attributedText = noStrikeThroughText(name) cell.accessoryType = UITableViewCell.AccessoryType.none cell.backgroundColor = .none } else if objectsArray[indexPath.row].strikeThrough == true && objectsArray[indexPath.row].accessory == true && objectsArray[indexPath.row].color == true { cell.textLabel?.text = "\(num). \(name)" cell.textLabel?.attributedText = strikeThroughText(name) cell.accessoryType = UITableViewCell.AccessoryType.checkmark cell.backgroundColor = .systemGray3 } else { cell.textLabel?.text = "\(num). \(name)" cell.textLabel?.attributedText = strikeThroughText(name) cell.accessoryType = UITableViewCell.AccessoryType.none cell.backgroundColor = .systemGray2 } return cell }It works perfectly except that when I added the if statements in cellForRowAt it doesn't display the num.I want it to look like this:1. Patrick Mahomes, KC2. Deshaun Watson, HOU3. Aaron Rodgers, GB...but it looks like this:Patrick Mahomes, KCDeshaun Watson, HouAaron Rodgers, GB...All other functionalities work perfect. This is the only thing I cannot figure out why it is doing this. I remove the if statements from cellForRowAt and it displays the way I want it to but the other functionalities do not work right.I am sorry if it seemed like I didn't want to do what you proposed but I am trying.
Dec ’19
Reply to How do I save a table view?
func strikeThroughText (_ text:String) -> NSAttributedString { let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: text) attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: 1, range: NSMakeRange(0, attributeString.length)) return attributeString } func noStrikeThroughText (_ text: String) -> NSAttributedString { let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: text) attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: 0, range: NSMakeRange(0, attributeString.length)) return attributeString } var strikeThroughTextBool: Bool = false
Dec ’19