How to make the deleteTask method work properly? - ios

I am trying to create a ToDoList in swift UI and my deleteTask function is not working properly. I tried a lot of things and none of them worked.
import UIKit
class ViewController: UIViewController {
#IBOutlet var tableView: UITableView!
var toDoTasks = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.title = "SAVED TASKS"
tableView.delegate = self
tableView.dataSource = self
// setup
if !UserDefaults().bool(forKey: "setup")
{
UserDefaults().set(true, forKey: "setup")
UserDefaults().set(0, forKey: "count")
}
updateTasks()
}
func updateTasks()
{
toDoTasks.removeAll()
guard let count = UserDefaults().value(forKey: "count") as? Int else
{
return
}
for x in 0..<count
{
if let task = UserDefaults().value(forKey: "task_\(x+1)") as? String
{
toDoTasks.append(task)
}
}
tableView.reloadData()
}
#IBAction func didTapAdd()
{
let viewController = storyboard?.instantiateViewController(withIdentifier: "entry") as! EntryViewController
viewController.title = "NEW TASK"
viewController.updated =
{
DispatchQueue.main.async {
self.updateTasks()
}
}
navigationController?.pushViewController(viewController, animated: true)
}
}
extension ViewController: UITableViewDelegate
{
// function to select the rows
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let viewController = storyboard?.instantiateViewController(withIdentifier: "task") as! TasksViewController
viewController.title = "NEW TASK"
viewController.task = toDoTasks[indexPath.row]
navigationController?.pushViewController(viewController, animated: true)
}
}
extension ViewController: UITableViewDataSource
{
// function which returns number of tasks
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return toDoTasks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = toDoTasks[indexPath.row]
return cell
}
}
import UIKit
class TasksViewController: UIViewController {
#IBOutlet var label : UILabel!
var task : String?
var currentPosition: Int?
override func viewDidLoad() {
super.viewDidLoad()
label.text = task
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Delete", style: .done, target: self, action: #selector(deleteTask))
}
#objc func deleteTask(_ sender: UIBarButtonItem) {
guard let currentPosition = self.currentPosition else {
return
}
let count = UserDefaults.standard.integer(forKey: "count")
UserDefaults.standard.removeObject(forKey: "task_\(currentPosition+1)")
for i in currentPosition+1..<count {
let task = UserDefaults.standard.string(forKey: "task_\(i+1)")
UserDefaults.standard.setValue(task, forKey: "task_\(i)")
}
UserDefaults.standard.setValue(count-1, forKey: "count")
navigationController?.popViewController(animated: true)
}
}
When I press the Delete button, nothing happens. Could you please help me??

Related

Sending data to another view controller but every data i send is nil or empty

all.
I am having a problem sending data.
I try to send data from AgentDetailVC to AbilitiesDetailsVC. But i cant. Every data i try to send is nil or empty string.I had managed to send before AgentListVC to AgentDetailsVC. Can y'all examine my code and help me please? Thank you a lot.
This is my AgenListVC.
import UIKit
class AgentListVC: UIViewController {
var agentsReference = ValorantReferenceApp().agents
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
self.tableView.rowHeight = 100
// tableView.separatorStyle = .none
tableView.delegate = self
tableView.dataSource = self
super.viewDidLoad()
configureNavigationBar()
}
//MARK: - Configure Navigation Bar
func configureNavigationBar() {
self.navigationController?.navigationBar.prefersLargeTitles = true
if var textAttributes = navigationController?.navigationBar.titleTextAttributes {
textAttributes[NSAttributedString.Key.foregroundColor] = UIColor.red
navigationController?.navigationBar.titleTextAttributes = textAttributes
}
}
}
//MARK: - Table View Methods
extension AgentListVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return agentsReference.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! AgentCellVC
let agent = agentsReference[indexPath.row]
cell.agentNameLAbel.text = agent.name
cell.agentImageview.image = agent.iconAgent
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "toSecondVC", sender: nil)
// tableView.deselectRow(at: indexPath, animated: true)
}
//MARK: - Prepare Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! AgentDetailVC
if let indexPath = tableView.indexPathForSelectedRow {
let agent = agentsReference[indexPath.row]
destinationVC.agentDetailVariables.choosenFlagImage = agent.agentFlagImage
destinationVC.agentDetailVariables.choosenAgentIconImage = agent.iconAgent
destinationVC.agentDetailVariables.choosenAgentType = agent.type.rawValue
destinationVC.agentDetailVariables.choosenAgentName = agent.name
destinationVC.choosenAgentAbilities = agent.abilities
destinationVC.agentDetailVariables.choosenAgentAbilitiesImages = agent.agentAbilitiesImage
destinationVC.choosenAgentVideoLink = agent.skillAbilitiesLink
}
}
}
This is my AgentDetailVC.
import UIKit
class AgentDetailVC: UIViewController {
#IBOutlet var typeLabel: UILabel!
#IBOutlet var characterImageView: UIImageView!
#IBOutlet var flagImageView: UIImageView!
#IBOutlet var tableView: UITableView!
#IBOutlet var agentTypeImageView: UIImageView!
var agentDetailVariables = AgentDetailVariables()
var agentsReference = ValorantReferenceApp().agents
var choosenAgentAbilities = [String]()
var viewController = AbilitiesDetailsViewController()
var choosenAgentVideoLink = [String]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
viewLoad()
print(choosenAgentAbilities)
}
//MARK: - ViewLoad Function.
func viewLoad() {
flagImageView.image = agentDetailVariables.choosenFlagImage
characterImageView.image = agentDetailVariables.choosenAgentIconImage
typeLabel.text = agentDetailVariables.choosenAgentType
title = agentDetailVariables.choosenAgentName
tableView.rowHeight = 65
tableView.separatorStyle = .none
agentTypeImageView.image = UIImage(named: "\(agentDetailVariables.choosenAgentType)")
// print(agentDetailVariables.choosenAgentVideoLink)
}
}
//MARK: - TableView Methods
extension AgentDetailVC : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return choosenAgentAbilities.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath) as! AgentDetailsCellVC
let agentAbilities = choosenAgentAbilities[indexPath.row]
let skillImages = agentDetailVariables.choosenAgentAbilitiesImages[indexPath.row]
print(agentAbilities)
cell.skillNameLabel.text = agentAbilities
cell.skillImageView.image = skillImages
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "toYoutubeVideos", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toYoutubeVideos" {
let destinationVC = segue.destination as! AbilitiesDetailsViewController
if let indexPath = tableView.indexPathForSelectedRow {
let agent = agentsReference[indexPath.row]
let link = choosenAgentVideoLink[indexPath.row]
print(link)
destinationVC.agentAbilitiesVideoURL = link
destinationVC.choosenAgentSkillName = choosenAgentAbilities[indexPath.row]
}
}
}
}
This is my AbilitiesDetailsViewController
import UIKit
import AVKit
import AVFoundation
import MediaPlayer
import MobileCoreServices
import YoutubePlayer_in_WKWebView
class AbilitiesDetailsViewController: UIViewController, AVPlayerViewControllerDelegate {
#IBOutlet var skillDetailsLabel: UILabel!
#IBOutlet var skillNameLabel: UILabel!
#IBOutlet var heroIconImageView: UIImageView!
var agentAbilitiesVideoURL = ""
var choosenAgentSkillName = ""
override func viewDidLoad() {
skillNameLabel.text = choosenAgentSkillName
super.viewDidLoad()
//playAbilitiesVideos()
}
#IBAction func playVideoUsingURL(_ sender: Any) {
playGlobalVideo()
}
func playGlobalVideo() {
guard let videoURL = URL(string: agentAbilitiesVideoURL ?? "sad") else {
return
}
let player = AVPlayer(url: videoURL)
let vc = AVPlayerViewController()
vc.player = player
present(vc, animated: true) {
player.play()
}
}
func playAbilitiesVideos() {
let player = AVPlayer(url: URL(string: "https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/bltf4e7a6525fe6ec42/625f2c7cfd9afd4b1fe300ee/C-Prowler_video.mp4")!)
let controller = AVPlayerViewController()
present(controller, animated: true) { }
controller.player = player
addChild(controller)
view.addSubview(controller.view)
controller.view.frame = CGRect(x: 50 , y: 50, width: 300, height: 300)
controller.player = player
controller.showsPlaybackControls = true
player.isClosedCaptionDisplayEnabled = false
player.play()
}
}
This is my struct.
struct Agent: Hashable{
let name: String
let type: AgentType
let origin: String
let abilities: [String]
let iconAgent : UIImage
let agentFlagImage : UIImage
let agentAbilitiesImage: [UIImage]
let skillAbilitiesLink: [String]
}
enum AgentType:String{
case controller = "Controller"
case sentinel = "Sentinel"
case initiator = "Initiator"
case duelist = "Duelist"
}
This is my Agents.
struct ValorantReferenceApp {
static var agentIconImages = AgentIconImages()
static var agentFlagImages = AgentFlagImages()
static var agentAbilitiesImages = AgentAbilitiesImages()
var agents: [Agent] = [
Agent(name: "Brimstone", type: .controller, origin: "United States", abilities: ["Incendiary",
"Stim Beacon",
"Sky Smoke",
"Orbital Strike"],
iconAgent: agentIconImages.iconBrimstone!,
agentFlagImage: agentFlagImages.flagBrimstone!,
agentAbilitiesImage: agentAbilitiesImages.abilitiesBrimstone, skillAbilitiesLink:
["https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/blte2b9eb1923ef64fa/5ecad7d0f5bd13348a6cac75/Brimstone_Q_v001_web.mp4",
"https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/bltc34c3d692ea83f41/5ecad7d0177c51692beb1fe4/Brimstone_C_v001_web.mp4",
"https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/bltcf4359fed083686b/5ecad7d198f79d6925dbee07/Brimstone_E_v001_web.mp4",
"https://assets.contentstack.io/v3/assets/bltb6530b271fddd0b1/blt3d19d83ba51eb18f/5ecad7d297b46c1911ad1868/Brimstone_X_v001_web.mp4"
])
]
In AgentDetailVC you have this code:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "toYoutubeVideos", sender: nil)
}
When the user selects a Row, the first thing you've done is deselect that row. You then call performSegue.
In prepare(for segue:...) you do this:
if let indexPath = tableView.indexPathForSelectedRow {
So -- tableView.indexPathForSelectedRow will always be nil because you just set it to nil.
Call .deselectRow after you perform the segue.

Add Animation on TableView Cells

I have made a tableView with cells that take the data from an API. I have imported ViewAnimator Package because I want to add some animation when the cells appear but the animation starts while the tableview had already be presented with data.
Maybe I have made a mistake at the logic but I can't find the solution.
The OpeningViewController is this :
import UIKit
import ViewAnimator
class OpeningViewController: UIViewController {
//MARK: - IBProperties
#IBOutlet var openingImg: UIImageView!
#IBOutlet var startButton: UIButton!
//MARK: - Properties
var nft : Nft?
//MARK: - Life Cyrcle
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let animation = AnimationType.from(direction: .top, offset: 50)
openingImg.animate(animations: [animation] , delay: 0.3, duration: 2)
openingImg.layer.shadowColor = UIColor.black.cgColor
openingImg.layer.shadowOffset = CGSize(width: 0, height: 0)
openingImg.layer.shadowOpacity = 0.65
openingImg.layer.shadowRadius = 10
}
//MARK: - Methods
#IBAction func startApp(_ sender: Any) {
HapticsManager.shared.selectionVibrate()
let storyBoard = UIStoryboard(name: "Lobby", bundle: nil)
let controller = storyBoard.instantiateViewController(withIdentifier: "LobbyViewController") as! LobbyViewController
controller.modalTransitionStyle = .flipHorizontal
self.navigationController?.pushViewController(controller, animated: true)
}
}
The presentation happens in LobbyViewController :
import UIKit
import ViewAnimator
class LobbyViewController: UIViewController {
// MARK: - IBProperties
#IBOutlet weak var tableView: UITableView!
// MARK: - Properties
var data: [DataEnum] = []
var likes:[Int] = []
var numlikes: Int = 0
var nfts: [Nft] = []
let creators : [Creator] = []
var icons: [Icon] = []
var loadData = APICaller()
// MARK: - Life Cyrcle
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: "AssetTableViewCell", bundle: nil)
tableView.register(nib, forCellReuseIdentifier: "AssetTableViewCell")
let nib2 = UINib(nibName: "CreatorsTableViewCell", bundle: nil)
tableView.register(nib2, forCellReuseIdentifier: "CreatorsTableViewCell")
tableView.dataSource = self //method to generate cells,header and footer before they are displaying
tableView.delegate = self //method to provide information about these cells, header and footer ....
downloadJSON {
self.tableView.reloadData()
print("success")
}
loadData.downloadData { (result) in
print(result)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let animation = AnimationType.from(direction: .top, offset: 300)
UIView.animate(views: tableView.visibleCells,
animations: [animation], delay: 1, duration: 2)
}
//stelnei ta dedomena apo to kathe row ston PresentViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? PresentViewController {
if tableView.cellForRow(at: tableView.indexPathForSelectedRow!) is AssetTableViewCell {
destination.nft = nfts[tableView.indexPathForSelectedRow!.row-1]
destination.delegate = self
} else {
//add alert action
let alert = UIAlertController(title: "Invalid Touch", message: "You press wrong row. Choose one of the following list.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(alert, animated: true, completion: {
return
})
}
}
}
// MARK: - Methods
func downloadJSON(completed: #escaping () -> ()) {
let url = URL(string: "https://public.arx.net/~chris2/nfts.json")
URLSession.shared.dataTask(with: url!) { [self] data, response, error in
if error == nil {
do {
self.nfts = try JSONDecoder().decode([Nft].self, from: data!)
let creators = nfts.map { nft in
nft.creator
}
self.data.append(.type1(creators: creators))
self.nfts.forEach { nft in
self.data.append(.type2(nft: nft))
}
DispatchQueue.main.async {
completed()
}
}
catch {
print("error fetching data from api")
}
}
}.resume()
}
}
// MARK: - Extensions
extension LobbyViewController : UITableViewDelegate , UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
indexPath.row == 0 ? 100 : UITableView.automaticDimension
}
//gemizo ta rows tou table
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch self.data[indexPath.item] {
case .type1(let creators):
print("--->", creators)
let cell = tableView.dequeueReusableCell(withIdentifier: "CreatorsTableViewCell",
for: indexPath) as! CreatorsTableViewCell
cell.layer.cornerRadius = 15
cell.layer.shadowColor = UIColor.black.cgColor
cell.layer.shadowOffset = CGSize(width: 0, height: 0)
cell.layer.shadowOpacity = 0.8
cell.layer.shadowRadius = 15
cell.layer.cornerRadius = cell.frame.height/2
cell.updateCreators(creators)
return cell
case .type2(let nft):
let cell = tableView.dequeueReusableCell(withIdentifier: "AssetTableViewCell",
for: indexPath) as! AssetTableViewCell
cell.nameLabel?.text = nft.name
cell.nameLabel.layer.cornerRadius = cell.nameLabel.frame.height/2
cell.likesLabel?.text = "\((numlikes))"
let imgUrl = (nft.image_url)
print(imgUrl)
cell.iconView.downloaded(from: imgUrl)
cell.iconView.layer.cornerRadius = cell.iconView.frame.height/2
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showDetails", sender: self)
}
}
extension LobbyViewController : TestDelegate{
func sendBackTheLikess(int: Int) {
numlikes = int
tableView.reloadData()
}
}
// MARK: - Enums
enum DataEnum {
case type1(creators: [Creator])
case type2(nft: Nft)
}
// MARK: - Struct
struct Constants {
static let url = "https://public.arx.net/~chris2/nfts.json"
}
The APICaller :
import Foundation
final class APICaller {
static let shared = APICaller()
public struct Constants {
static let url = "https://public.arx.net/~chris2/nfts.json"
}
public func downloadData(completion:#escaping (Result<[Nft], Error>) -> Void )
{
guard let url = URL(string:Constants.url)else{
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
//print(response)
print("here")
guard let data = data , error == nil else{
print("something went wrong with data")
return
}
print("here4")
//mexri edo exoume parei ta data kai tora me to do-catch tha ta kanoume convert se object
do{
//Decode the response
let nfts = try JSONDecoder().decode([Nft].self, from: data)
completion(.success(nfts))
print(nfts)
}catch{
completion(.failure(error))
}
}
task.resume()
}
}
and here is a video as a gif of what happen fro better understanding
https://gifyu.com/image/SEGkZ

How to fix deleted task being restored in Userdefaultrs

I'm making a TodoList app.
If you swipe a task from the list to delete it and then add a new task, the deleted task will be restored.
Use storyboard and UIKit.
I want to keep it deleted, what should I do? ..
mac 10.15.7
xcode 12.1
import UIKit
class ViewController: UIViewController {
#IBOutlet var tableView: UITableView!
var tasks = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "リスト"
tableView.delegate = self
tableView.dataSource = self
if !UserDefaults().bool(forKey: "setup") {
UserDefaults().set(true, forKey: "setup")
UserDefaults().set(0, forKey: "count")
}
updateTasks()
}
func updateTasks() {
tasks.removeAll()
guard let count = UserDefaults().value(forKey: "count") as? Int else {
return
}
for x in 0..<count {
if let task = UserDefaults().value(forKey: "task_\(x+1)") as? String {
tasks.append(task)
}
}
tableView.reloadData()
}
#IBAction func didTapAdd() {
let vc = storyboard?.instantiateViewController(identifier: "entry") as! EntryViewController
vc.title = "リストに追加"
vc.update = {
//非同期処理 更新を優先
DispatchQueue.main.async {
self.updateTasks()
}
}
navigationController?.pushViewController(vc, animated: true)
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let vc = storyboard?.instantiateViewController(identifier: "task") as! TaskViewController
vc.title = "リストに追加"
vc.task = tasks[indexPath.row]
navigationController?.pushViewController(vc, animated: true)
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tasks.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = tasks[indexPath.row]
return cell
}
//タスクを削除
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let index = indexPath.row
tasks.remove(at: index)
let userDefaults = UserDefaults.standard
userDefaults.set(tasks, forKey: "tasks")
userDefaults.removeObject(forKey: "tasks")
tableView.reloadData()
}
}
Is remove (at :) different?
import UIKit
class EntryViewController: UIViewController, UITextFieldDelegate {
#IBOutlet var field: UITextField!
var update: (() -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
field.delegate = self
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "保存", style: .done, target: self, action: #selector(saveTask))
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
saveTask()
return true
}
#objc func saveTask() {
guard let text = field.text, !text.isEmpty else {
return
}
guard let count = UserDefaults().value(forKey: "count") as? Int else {
return
}
let newCount = count + 1
UserDefaults().set(newCount, forKey: "count")
UserDefaults().set(text, forKey: "task_\(newCount)")
update?()
navigationController?.popViewController(animated: true)
}
}
How to save UserDefaults?
The problem I see is; in updateTasks function, you get the tasks from UserDefaults by keys as task_1, task_2 etc. But when deleting a specific task, lets say task_2, you are just removing it from tasks array, not deleting it from UserDefaults. So whenever you call updateTasks function, the deleted task re-appears.
In your EntryViewController, change the saveTask function with following:
#objc func saveTask() {
guard let text = field.text, !text.isEmpty else {
return
}
let tasks = UserDefaults.standard.array(forKey: "tasks") as? [String] ?? []
tasks.append(text)
UserDefaults.standard.set(tasks, forKey: "tasks")
update?()
navigationController?.popViewController(animated: true)
}
In your ViewController, change the following functions:
func updateTasks() {
tasks.removeAll()
tasks = UserDefaults.standard.array(forKey: "tasks") as? [String] ?? []
tableView.reloadData()
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
tasks.remove(at: indexPath.row)
let userDefaults = UserDefaults.standard
userDefaults.set(tasks, forKey: "tasks")
updateTasks()
}

Unable to get my "Save" Button to work, my button does nothing when pressed

I'm trying to make a note taking app, however, I'm kinda stuck on how to get my save button to work. Here's what I've got so far:
My Add "Item" View
class AddViewController: UIViewController {
#IBOutlet var addShortDescription: UITextField!
#IBOutlet var addLongDescription: UITextView!
public var completion: ((String, String) -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
addShortDescription.becomeFirstResponder()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Save", style: .done, target: self, action: #selector(didTapSave))
self.title = "Add New Item"
}
#IBAction func didTapSave(_ sender: Any) {
if let text = addShortDescription.text, !text.isEmpty, !addLongDescription.text.isEmpty {
completion?(text, addLongDescription.text)
}
}
}
My Main View
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var table: UITableView!
var models: [(ShortDescription: String, LongDescription: String)] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
table.delegate = self
table.dataSource = self
self.title = "Inventory"
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return models.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = models[indexPath.row].ShortDescription
cell.detailTextLabel?.text = models[indexPath.row].LongDescription
return cell
}
#IBAction func addNewInventory(){
guard let vc = storyboard?.instantiateViewController(identifier: "add") as? AddViewController else {
return
}
vc.title = "Add New Item"
vc.navigationItem.largeTitleDisplayMode = .never
vc.completion = { addShortDescription, addLongDescription in
self.navigationController?.popToRootViewController(animated: true)
self.models.append((ShortDescription: addShortDescription, LongDescription: addLongDescription))
self.table.isHidden = false
self.table.reloadData()
}
navigationController?.pushViewController(vc, animated: true)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let model = models[indexPath.row]
// Show addLongDescription controller
guard let vc = storyboard?.instantiateViewController(identifier: "inventory") as?
EditViewController else {
return
}
vc.navigationItem.largeTitleDisplayMode = .never
vc.title = "Edit Item"
vc.addShortDescription.text = model.ShortDescription
vc.addLongDescription.text = model.LongDescription
navigationController?.pushViewController(vc, animated: true)
}
}
I have another view where I plan on allowing the user to edit the added items, I'll add that if you think it may be causing some problems.

TableView limit use (Swift)

Hello i have two viewControllers, the first with a stepper
var steppers : UIStepper?
#IBOutlet weak var hourLabel: UILabel!
#IBAction func stepper(_ sender: UIStepper) {
hourLabel.text = String(sender.value)
}
and the second with a tableView
import UIKit
import AVFoundation
class SelectClass: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var list : [QCategoryy] = [QCategoryy]()
var audioPlayer : AVAudioPlayer!
var limit = 3
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.allowsMultipleSelection = true
self.title = "Categories"
list = NearbyPlaces.getCategories()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
list.sort() { $0.views > $1.views}
tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func backTapp(_ sender: Any) {
let audioUrl = NSURL.fileURL(withPath: Bundle.main.path(forResource: "pop_drip", ofType: "m4a")!)
do{
try AVAudioSession.sharedInstance().setActive(true)
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try audioPlayer = AVAudioPlayer(contentsOf: audioUrl)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
catch _ as NSError
{
}
dismiss(animated: true, completion: nil)
}
#IBAction func doneTapp(_ sender: Any) {
let audioUrl = NSURL.fileURL(withPath: Bundle.main.path(forResource: "pop_drip", ofType: "m4a")!)
do{
try AVAudioSession.sharedInstance().setActive(true)
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try audioPlayer = AVAudioPlayer(contentsOf: audioUrl)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
catch _ as NSError
{
}
self.performSegue(withIdentifier: nearbySearchSegueIdentifier, sender: nil)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "CATEGORY_CELL"
let cell = tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath)
let selectedIndexPaths = tableView.indexPathsForSelectedRows
let rowIsSelected = selectedIndexPaths != nil && selectedIndexPaths!.contains(indexPath)
/* cell.accessoryType = rowIsSelected ? .checkmark : .none */
cell.accessoryType = list[indexPath.row].isSelected ? .checkmark : .none
cell.textLabel?.text = list[indexPath.row].name
return cell
}
let nearbySearchSegueIdentifier = "goToMcourse"
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)!
cell.accessoryType = .checkmark
/* self.performSegue(withIdentifier: nearbySearchSegueIdentifier, sender: list[indexPath.row]) */
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)!
cell.accessoryType = .none
}
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if let sr = tableView.indexPathsForSelectedRows {
if sr.count == limit {
let alertController = UIAlertController(title: "Oops", message:
"You are limited to \(limit) selections", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {action in
}))
self.present(alertController, animated: true, completion: nil)
return nil
}
}
return indexPath
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == nearbySearchSegueIdentifier {
guard let category = sender as? QCategoryy else {
return
}
if let selectedRows = tableView.indexPathsForSelectedRows {
if let vc = segue.destination as? CourseClass2 {
vc.category = category
}
}
}
}
}
extension QCategoryy {
private static let ketPrefix = "category-"
var views:Int {
get {
return UserDefaults.standard.integer(forKey: QCategoryy.ketPrefix + name)
}
}
func markView() {
UserDefaults.standard.set(views + 1, forKey: QCategoryy.ketPrefix + name)
}
}
in this tableView i can select multiple cells and add a limit to the selection with the var
var limit = 3
and the func
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if let sr = tableView.indexPathsForSelectedRows {
if sr.count == limit {
let alertController = UIAlertController(title: "Oops", message:
"You are limited to \(limit) selections", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {action in
}))
self.present(alertController, animated: true, completion: nil)
return nil
}
}
return indexPath
}
but what i would like to do is to use the stepper in the first viewController to add the limit at the selection of the tableView (in the second viewController), something like
How can i do it?
In the VC with the stepper, override prepareForSegue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? SelectClass {
vc.limit = Int(stepper.value)
}
}
EDIT: You need to make the stepper an outlet of the VC, change the the declaration to this first:
#IBOutlet var stepper: UIStepper!
In the storyboard, right click on your view controller (the one with the yellow icon):
Then this appears:
See the stepper under "Outlets"? Drag from the circle besides the stepper to the stepper on your storyboard:

Resources