Table Cell Not Swiping - ios

I'm developing a todo list app that links up with a Realm database, however when I'm trying to use the 'editingStyle' method which allows users to swipe on the cell to delete the data from the UI & the Realm database the cell doesn't swipe, the app has 2 screens, this method works fine on one the first one but it does not work on the other screen, the cell works fine it just won't swipe.
My code:
import UIKit
import RealmSwift
class CategoryViewController: UITableViewController {
var categories: Results<Category>?
let realm = try! Realm()
override func viewDidLoad() {
super.viewDidLoad()
loadCategories()
tableView.rowHeight = 60.0
}
//MARK: - Creating the table view cell
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return categories?.count ?? 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for: indexPath)
cell.textLabel?.text = categories?[indexPath.row].name ?? "No Categories Added Yet"
return cell
}
//MARK: - This will remove a category from the UI & the Realm database, this is a built in swift method
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
if let deleteAction = categories?[indexPath.row] {
do {
try realm.write({
realm.delete(deleteAction)
})
} catch {
print("Error deleting the cell \(error)")
}
}
}
tableView.deleteRows(at: [indexPath], with: .fade)
}
//MARK: - TableView Delegate Methods
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "goToItems", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! TodoListViewController
if let indexPath = tableView.indexPathForSelectedRow {
destinationVC.selectedCategory = categories?[indexPath.row]
}
}
//MARK: - Add New Categories
#IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
var textField = UITextField()
let alert = UIAlertController(title: "Add New Category", message: "", preferredStyle: .alert)
let action = UIAlertAction(title: "Add", style: .default) { (action) in
// What happens when user clicks add button
let newCategory = Category()
newCategory.name = textField.text!
self.saveCategories(category: newCategory)
}
alert.addAction(action)
alert.addTextField { (field) in
textField = field
textField.placeholder = "Add a new category"
}
present(alert, animated: true, completion: nil)
}
//MARK: - Data Manipulation Methods
func saveCategories(category: Category) {
do {
try realm.write({
realm.add(category)
})
} catch {
print("Error saving category \(error)")
}
tableView.reloadData()
}
func loadCategories() {
categories = realm.objects(Category.self)
tableView.reloadData()
}
}

Add this:
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}

Your code seems correct. I think there's something wrong with realm.delete(_:) method which possibly throws an error which executes the catch block instead of deleting the row. Try to see if there is something wrong within the try block with a few print statements. And if all fails, try making the following changes
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
if let deleteAction = categories?[indexPath.row] {
do {
try realm.write({
realm.delete(deleteAction)
})
// New snippet
tableView.deleteRows(at: indexPath, with: .fade)
self.tableView.reloadData()
} catch {
print("Error deleting the cell \(error)")
}
}
}
}

Related

Swipe to delete function insert including Core Data

I am trying to do a Simple Name List app. I have watched this video and copied everything ( https://www.youtube.com/watch?v=tP4OGvIRUC4 )
I now want to add a Swipe to delete function. It works the way I want it to work but when I close and reopen the app it will be like before.
I tried different things but it did not work.
Anybody got any ideas?
Greets from Switzerland
Here is my ViewController:
import UIKit
import CoreData
class ViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
var people = [Person]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let fetchRequest: NSFetchRequest<Person> = Person.fetchRequest()
do {
let people = try PersistenceServce.context.fetch(fetchRequest)
self.people = people
self.tableView.reloadData()
}catch{}
}
#IBAction func onPlusTapped() {
let alert = UIAlertController(title: "Add name", message: nil, preferredStyle: .alert)
alert.addTextField { (textField) in
textField.placeholder = "Name"
}
let action = UIAlertAction(title: "Add", style: .default) { (_) in
let name = alert.textFields!.first!.text!
let person = Person(context: PersistenceServce.context)
person.name = name
PersistenceServce.saveContext()
self.people.append(person)
self.tableView.reloadData()
}
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
}
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return people.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
cell.textLabel?.text = people[indexPath.row].name
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
guard editingStyle == UITableViewCell.EditingStyle.delete else { return }
people.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
self.tableView.reloadData()
}
}
You are just removing the item from your local array, you need to persist the change after removing it.
when you reload apps your table take again data from fetch, where your deleted data stay. if you like delete data in fetch look at this topic
Core Data Delete Object
This is how i have done it previously.
override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
// deleteAction, Call the deleteobject function, and then reload the data
let deleteAction = UITableViewRowAction(style: .default, title: DELETE_TITLE) { (rowAction, indexPath) in
_ = deleteObject(name: self.dataSource[indexPath.row].name)
self.tableview.reload()
}
return [deleteAction]
}
func deleteObject(name: String) -> Bool {
let context = getContext()
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: ENTITY_NAME)
fetchRequest.predicate = NSPredicate(format: formatStringForPredicate(oldListName: name))
let objects = try! context.fetch(fetchRequest)
for obj in objects {
context.delete(obj as! NSManagedObject)
}
do {
try context.save()
return true
} catch {
return false
}
}
Note you may need to modify deleteObject function.
First of all never call reloadData() right after insertRows(at or deleteRows(at because the insert/delete methods do update the UI.
To make the deletion persistent you have to delete the item in the context and save the context.
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
guard editingStyle == .delete else { return }
let personToDelete = people.remove(at: indexPath.row)
PersistenceServce.context.delete(personToDelete)
tableView.deleteRows(at: [indexPath], with: .automatic)
PersistenceServce.saveContext()
}
In order to do anything with core data, it needs to load all necessary objects to memory, which is going to be accessed by your context, once you load the item you want to delete to the context all you need to do is simply
context.delete(item)
tableViewArray.remove(at: itemIndex in array)
Then call the context.save() to save the changes you made to the persistence store

Delete not working and last value not display, User default with tableview

I implemented to save data in local using user dafaults with table view. when insert data every data display in my tableview. but stop and run again last value is not dispayed. and when swipe and remove not working when app run next time.
import UIKit
let defaults = UserDefaults(suiteName: "com.saving.data")
class HomeWorkViewController: UITableViewController {
var rows = [String]()
call getData() method in viewDidload
override func viewDidLoad() {
super.viewDidLoad()
getData()
// Do any additional setup after loading the view.
self.navigationItem.rightBarButtonItem = self.editButtonItem
}
calling getData() method
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
getData()
}
calling storeData method
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(true)
storeData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func addButton(_ sender: Any) {
addCell()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rows.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "homeWork", for: indexPath)
cell.textLabel?.text = rows[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
rows.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
tableView.reloadData()
}else if editingStyle == .insert {
}
}
func addCell(){
let alert = UIAlertController(title: "Add Home Work", message: "Input text", preferredStyle: .alert)
alert.addTextField{(textField) in
textField.placeholder = "text...."
}
alert.addAction(UIAlertAction(title: "Confirm", style: .default, handler: {[weak alert](_) in
let row = alert?.textFields![0]
self.rows.append((row?.text)!)
self.tableView.reloadData()
}))
self.present(alert,animated: true, completion: nil)
storeData()
}
func storeData(){
defaults?.set(rows, forKey: "savedData")
defaults?.synchronize()
}
func getData(){
let data = defaults?.value(forKey: "savedData")
if data != nil {
rows = data as! [String]
}else{}
}
}
You call storeData() at the wrong place. The addAction closure is executed later in time.
func addCell() {
let alert = UIAlertController(title: "Add Home Work", message: "Input text", preferredStyle: .alert)
alert.addTextField{(textField) in
textField.placeholder = "text...."
}
alert.addAction(UIAlertAction(title: "Confirm", style: .default, handler: {[weak alert](_) in
let row = alert?.textFields![0]
let insertionIndex = self.rows.count
self.rows.append(row.text!)
self.tableView.insertRows(at: IndexPath(row: insertionIndex, section: 0), with: .automatic)
self.storeData()
}))
self.present(alert,animated: true, completion: nil)
}
And never call reloadData after calling deleteRows
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
rows.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
self.storeData()
}
}
And use the dedicated API of UserDefaults (don't call synchronize)
func storeData(){
defaults!.set(rows, forKey: "savedData")
}
func getData(){
rows = defaults!.array(forKey: "savedData") as? [String] ?? []
}

How to delete from tableview as well as sqlite3 using Swift

I'm new to swift and sqlite3 and I need help on how to delete from tableview and sql db.
I tried to use reloadData() but it doesn't work. I tried to delete using tableView.deleteRows(at: [indexPath], with: .fade) but Im getting an error as I have a sql delete statement running before that. With this code provided below, Im successfully able to remove the item from the database, but it doesn't refresh the tableview. The way I got around to fixing it temporarily is perform a segue to previous screen upon successful removal of an item and when returned to the tableviewcontroller it would be removed.
import UIKit
class TableViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
let mainDelegate = UIApplication.shared.delegate as! AppDelegate
#IBOutlet var tableView: UITableView!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let tableCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? SiteCell ?? SiteCell(style: .default, reuseIdentifier: "cell")
let rowNum = indexPath.row
tableCell.primaryLabel.text = mainDelegate.people[rowNum].name
tableCell.secondaryLabel.text = mainDelegate.people[rowNum].email
tableCell.myImageView.image = UIImage(named: mainDelegate.people[rowNum].avatar!)
tableCell.accessoryType = .disclosureIndicator
return tableCell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return mainDelegate.people.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 70
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let rowNum = indexPath.row
let details : String! = "Address: \(mainDelegate.people[rowNum].address!) \nPhone Num: \(mainDelegate.people[rowNum].phonenum!) \nEmail: \(mainDelegate.people[rowNum].email!) \nAge: \(mainDelegate.people[rowNum].age!) \nGender: \(mainDelegate.people[rowNum].gender!) \nDate of birth: \(mainDelegate.people[rowNum].dob!)"
let alertController = UIAlertController(title: mainDelegate.people[rowNum].name, message: details, preferredStyle: .alert
)
let cancelAction = UIAlertAction(title: "ok", style: .cancel, handler: nil)
print("TESTING ROW: \(mainDelegate.people[rowNum].id!)")
alertController.addAction(cancelAction)
present(alertController, animated: true)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
var rowNum: Int = indexPath.row
if editingStyle == .delete {
print("Testing delete \(mainDelegate.people[rowNum].id!)")
print("\(indexPath.row)")
mainDelegate.removeFromDatabase(id: mainDelegate.people[rowNum].id!)
print("\(indexPath)")
// tableView.deleteRows(at: [indexPath], with: .fade)
DispatchQueue.main.async{
self.tableView.reloadData()
}
// self.performSegue(withIdentifier: "DataToInfo", sender: self)
// let mainDelegate = UIApplication.shared.delegate as! AppDelegate
// mainDelegate.removeFromDatabase(person: mainDelegate.people[indexPath.row])
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
mainDelegate.readDataFromDatabase()
}
removeFromDatabase method
func removeFromDatabase(id : Int){
var db : OpaquePointer? = nil
if sqlite3_open(self.databasePath, &db) == SQLITE_OK{
print("Successfully opened connection to database at \(self.databasePath)")
var deleteStatement : OpaquePointer? = nil
let deleteStatementString : String = "delete from entries where id=\(id)"
if sqlite3_prepare_v2(db, deleteStatementString, -1, &deleteStatement, nil) == SQLITE_OK{
if sqlite3_step(deleteStatement) == SQLITE_DONE{
print("Deleted")
}
else{
print("Failed")
}
}else{
print("Couldn't prepare")
}
sqlite3_finalize(deleteStatement)
sqlite3_close(db)
}
}
Im trying to delete it from tableview as well as database. At one point I was trying to
mainDelegate.people.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
then running the removeFromDatabase, but it was giving me an error.
You should update your datasource. Try to refactor your commitEditing like this:
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
var rowNum: Int = indexPath.row
if editingStyle == .delete {
print("Testing delete \(mainDelegate.people[rowNum].id!)")
print("\(indexPath.row)")
mainDelegate.removeFromDatabase(id: mainDelegate.people[rowNum].id!)
print("\(indexPath)")
mainDelegate.readDataFromDatabase()
tableView.deleteRows(at: [indexPath], with: .fade)
}
}

Swift 3 - Rearrange and persist the cells in tableview

I have a tableview which I can add items to it and it will save to core data, I can also delete these items and it all works fine
However now I want to rearrange the cells and persist the data as well
At the moment I can select the barbutton Edit and it will allow me to rearrange the cells but the moment i leave the viewcontroller it will reset to how it was
Can someone please help me?
class CustomWorkoutViewController: UIViewController {
#IBOutlet weak var newMusclesTableView: UITableView!
var workout:Workout?
override func viewDidLoad() {
super.viewDidLoad()
newMusclesTableView.delegate = self
let nib = UINib(nibName: "muscleListTableViewCell", bundle: nil)
newMusclesTableView.register(nib, forCellReuseIdentifier: "workCell")
}
override func viewDidAppear(_ animated: Bool) {
self.newMusclesTableView.reloadData()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "addMuscles"{
guard let destination = segue.destination as? AddMusclesViewController else {
return
}
destination.workout = workout
}
else if segue.identifier == "addLogs"{
guard let destination = segue.destination as? WorkoutViewController,
let selectedRow = self.newMusclesTableView.indexPathForSelectedRow?.row else {
return
}
destination.muscleLog = workout?.muscleList?[selectedRow]
}
}
func btnAction(_ sender: UIButton) {
let point = sender.convert(CGPoint.zero, to: newMusclesTableView as UIView)
let indexPath: IndexPath! = newMusclesTableView.indexPathForRow(at: point)
let vc = viewMusclesViewController()
let viewTitle = workout?.muscleList?[indexPath.row]
vc.customInit(title: (viewTitle?.name)!)
vc.titleStr = viewTitle?.name
vc.gifStr = viewTitle?.muscleImage
navigationController?.pushViewController(vc, animated: true)
}
#IBAction func editAction(_ sender: UIBarButtonItem) {
self.newMusclesTableView.isEditing = !self.newMusclesTableView.isEditing
sender.title = (self.newMusclesTableView.isEditing) ? "Done" : "Edit"
}
func deleteMuscle(at indexPath: IndexPath){
guard let muscles = workout?.muscleList?[indexPath.row],
let managedContext = muscles.managedObjectContext else{
return
}
managedContext.delete(muscles)
do{
try managedContext.save()
newMusclesTableView.deleteRows(at: [indexPath], with: .automatic)
}catch{
print("Could not save")
newMusclesTableView.reloadRows(at: [indexPath], with: .automatic)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
And this is my tableview extension
extension CustomWorkoutViewController: UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return workout?.muscleList?.count ?? 0
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 70
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = newMusclesTableView.dequeueReusableCell(withIdentifier: "muscleCell", for: indexPath) as? muscleListTableViewCell
cell?.cellView.layer.cornerRadius = (cell?.cellView.frame.height)! / 2
if let muscles = workout?.muscleList?[indexPath.row]{
cell?.muscleTitle?.text = muscles.name
cell?.myBtn.addTarget(self, action: #selector(self.btnAction(_:)), for: .touchUpInside)
}
return cell!
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
deleteMuscle(at: indexPath)
}
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
//How to persist data here?
}
}
Your code decides which item to display for a row with this code:
if let muscles = workout?.muscleList?[indexPath.row]
The row order is going to be determined by the order in muscleList. The table view can rearrange cells when you use its edit mode, but it can't save that new order because it doesn't know how to change the order of muscleList. Your implementation of tableView(_:moveRowAt:to:) needs to change the order based on the table view update.
If muscleList is an ordered relationship, change the order. If it's not an ordered relationship then you'll need to add a property that you can use to sort the relationship-- even something as simple as a sortOrder property would do.
I managed to find a solution to my own question
I will post it here for future if anyone needed help
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let muscle = workout?.muscleList?[sourceIndexPath.row]
workout?.removeFromRawMuscles(at: sourceIndexPath.row)
workout?.insertIntoRawMuscles(muscle!, at: destinationIndexPath.row)
do{
try muscle?.managedObjectContext?.save()
}catch{
print("Rows could not be saved")
}
}

How to re-save data in UITableVIew without causing any duplicates of the same UITextVIew in Swift3

Userdefaults-saved data is passed from my TextViewCotroller to TextViewTableController successfully, but not perfectly successful. This is because when my TextView, which has some data already, is re-saved, it causes a duplicate.
For example, if the firstly saved data is like "hello, I like bagels" and if I edit it to like "hello, I like bagels and chololate cookies" and re-save it,
At the 0 index of my TableView is "hello, I like bagels and chololate cookies"
At the 1 index of my TableView is "hello, I like bagels"
When this is repeatedly done, there are multiple duplicates of the same text in my TableView. This is so annoying that I really want to detect the cause of this issue. However, I have no idea of fixing this bug.
TextTableViewController:
class TextTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
self.tableView.reloadData()
}
func saveTextData() -> [String] {
if let textData = userTextDataSave.array(forKey: "txtData") as? [String] {
return textData
}
return []
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return saveTextData().count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellForText", for: indexPath)
cell.backgroundColor = UIColor.clear
cell.preservesSuperviewLayoutMargins = false
cell.textLabel?.text = saveTextData()[indexPath.row]
cell.textLabel?.font = UIFont.systemFont(ofSize: 20)
tableView.reloadData()
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
removeHistory(index: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "text",sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any!) {
if (segue.identifier == "text") {
let subVC: TextViewController = (segue.destination as? TextViewController)!
let indexPath = tableView.indexPathForSelectedRow;
subVC.textFromCell = saveTextData()[(indexPath?.row)!]
}
}
}
TextViewController and functions for saving text data:
func save(){
let alert = UIAlertController(title: "titile", message: "save?", preferredStyle: .alert)
let noAction = UIAlertAction(title: "Cancel", style: .default, handler: { Void in
})
let okAction = UIAlertAction(title: "Save", style: .default, handler: { Void in
self.addTextData(text: self.myTextView.text)
})
alert.addAction(noAction)
alert.addAction(okAction)
present(alert, animated: false, completion: nil)
}
func saveTextData() -> [String] {
if let textData = userTextDataSave.array(forKey: "txtData") as? [String] {
return textData
}
return []
}
func addTextData(text: String) {
var data = saveTextData()
for d in data {
if d == "" {
return
}
}
data.insert(text, at: 0)
userTextDataSave.set(text, forKey: "txtData")
userTextDataSave.synchronize()
}
Try this :
func addTextData(text: String) {
var data = saveTextData()
for d in data {
if d == "" {
return
}
if d == text {
return
}
}
userTextDataSave.set(text, forKey: text)
userTextDataSave.synchronize()
}

Resources