How can i pass Label from viewController to another one without using segue? - arrays

Hi im new in swift and im trying to build a store application, i already build it but i have a problem with only one thing which is , i want to pass the data ( label, image, price label ) to another viewController without using segue. I tried all the method ( delegate, notificationCenter, closure ) but i didn't solve it.
this is a picture for new project i create it to explain what i want to do exactly .
i hope i get the solution because i search alot for it maybe for months but i didn't solve my problem :(
this is my code
passingViewController
import UIKit
extension passingDataViewController : textDelegate {
func sendText(withText: String) {
Label.text = withText
}
}
class receivingDataViewController: UIViewController {
#IBOutlet var label2: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
}
receivingDataViewController
import UIKit
extension passingDataViewController : textDelegate {
func sendText(withText: String) {
Label.text = withText
}
}
class receivingDataViewController: UIViewController {
#IBOutlet var label2: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
}

You didn't explain how you're creating the new controllers, but here's a simple example that just uses a tab controller. This makes use of a shared singleton to pass around the delegate, but if you're creating each controller programatically, you could update the delegate when you create each new instance.
For this example, I have created a singleton that contains the delegate
import Foundation
class SharedSingleton : NSObject
{
var updateDelegate : UpdateDelegate?
static let sharedInstance = SharedSingleton()
}
And then we define the protocol you're using.
In the passing view, you can define it like this
protocol UpdateDelegate
{
func updateDisplay(text : String)
}
and you use it (in the passing view like this
var sharedInstance = SharedSingleton.sharedInstance
#IBAction func cmdGo(_ sender: Any) {
sharedInstance.updateDelegate!.updateDisplay(text: txtInput.text!)
}
You define the receiving view to use the update protocol
class ReceivingViewController: UIViewController, UpdateDelegate {
and set up the delegate
var sharedInstance = SharedSingleton.sharedInstance
override func viewDidLoad() {
super.viewDidLoad()
// setup the delegate through the shared instance
sharedInstance.updateDelegate = self
}
and then implement the update method
func updateDisplay(text: String) {
lblDisplay.text = text
}
That's it. You may need to update your implementation to change how you share the delegate pointer, but that's the process.

Related

Refresh Custom Table View when coming back to its View Controller

I want to refresh my Table View after inserting data in it.
So what I'm doing is I click a button, the buttons opens another View Controller where I insert the data then press a button to add that data to an array(Object) and then It goes back to the Table View Controller, and here I want to swipe to refresh my Table View.
Here is my code:
ViewController.swift
AddProcessador.swift
I'm not exactly sure what you mean by refreshing your table view by swiping.
But I have two ideas that might work for you.
If you have only these two view controllers and you accept that the table view is also reloaded, for example, right at startup (first call of viewDidLoad), this would be a possibility:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tableView.reloadData()
}
If you want to refresh the table view only after saving the entries, you could also create a protocol and use it.
// Create the protocol
protocol ReloaderDelegate {
func reloadTableView()
}
// Set up a variable in your AddProcessador view controller
var delegate: ReloaderDelegate?
// Set the delegate to a value when you create the AddProcessador instance in the ViewController
controller = self
// Now you can call the function in your AddProcessador view controller
delegate?.reloadTableView()
As a complete code:
protocol ReloaderDelegate {
func reloadTableView()
}
class AddProcessador: UIViewController {
var delegate: ReloaderDelegate?
// Your IBOutlets
override func viewDidLoad() {
super.viewDidLoad()
// ...
}
#IBAction func addClick(_ sender: Any) {
// 1. Add your new processador
// 2. Reload your table view
delegate?.reloadTableView()
// 3. Go back
navigationController?.popViewController(animated: true)
}
}
class ViewController: UIViewController, ReloaderDelegate {
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// ...
}
func reloadTableView() {
self.tableView.reloadData()
}
#IBAction func pushAddProcessador() {
let controller = AddProcessador()
controller.delegate = self
navigationController?.pushViewController(controller, animated: true)
}
}
Please excuse me if I have made a mistake somewhere.
I hope I could help you with this somehow.
override func viewDidLoad() {
super.viewDidLoad()
refreshControl?.addAction(UIAction(handler: { _ in
DispatchQueue.main.async {
self.tableView.reloadData()
}
}), for: .primaryActionTriggered)
}
override func numberOfSections(in tableView: UITableView) -> Int {
refreshControl?.endRefreshing() //this can be moved to number of rows in section as well. We just need to tell the control we have data and to stop spinning.
return 1
}

PHPicker delegate error: PHPickerViewControllerDelegate doesn't respond to picker:didFinishPicking

In WWDC20 apple introduced PHPicker, the replacement for UIImagePickerController.
I have a wrapper NSObject class witch handles all the configuration and presentation of image picker controller, now I'm replacing the implementation to support iOS14.
Even if I set the delegate to be self I get the error:
[Picker] PHPickerViewControllerDelegate doesn't respond to picker:didFinishPicking:
I think it checks on the parent view controller, that indeed it's not implementing the delegate methods but the wrapper does.
Here is my example code:
import Foundation
import PhotosUI
class myPicker: PHPickerViewControllerDelegate{
func openFrom(parent:UIViewController!) {
var config:PHPickerConfiguration! = PHPickerConfiguration()
config.selectionLimit = 1
config.filter = nil
let pickerViewController:PHPickerViewController! = PHPickerViewController(configuration:config)
pickerViewController.delegate = self //<---
parent.present(pickerViewController, animated:true, completion:nil)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true, completion:nil)
for result:PHPickerResult in results {
let itemProvider:NSItemProvider = result.itemProvider
print(itemProvider)
}
// ...do something with images...
}
}
Using it...
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let mypicker = myPicker()
mypicker.openFrom(parent: self)
}
What do you suggest?
The problem is that Cocoa Objective-C cannot introspect your class. Change
class myPicker: PHPickerViewControllerDelegate
To
class myPicker: NSObject, PHPickerViewControllerDelegate
You need to make "class myPicker" as a singleton class. Because you should make sure delegate not to be nil. Also, you can change this instance = nil in the didFinishPicking method.

Updating array value using find object in the background is swift

I'm trying to retrieve data from Parse using findObjectsInbackground and store it in an array. I've already created outside the scoop of viewDidLoad().
I managed retrieving and printing the data, but they are not stored in the array and it keeps being empty!
I used self.articalsTableView.reloadData() but unfortunately the array myArray is still empty.
Any help please, this has been confusing me for two days!
import UIKit
import Parse
class FirstViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var articalsTableView: UITableView!
var myArray = [PFObject]()
override func viewDidLoad() {
super.viewDidLoad()
let query = PFQuery(className: "Gateshead")
query.findObjectsInBackground {(objects, error) -> Void in
if error != nil {
print(error)
} else {
if let articals = objects {
for artical in articals {
// print (articles) THIS IS WOKING WELL
self.myArray.append(artical)
self.articalsTableView.reloadData()
}
}
}
}
}
}
findObjectsInback is using a background thread and you should dispatch to mainThread whenever if you want to access UIKit stuff in this case updating self.articalsTableView.
Also self.articalsTableView.reloadData() should be called at the end (not in the loop). This to prevent a race condition on self.myArray being accessed by the main-thread (to update self.articalsTableView ) and by the background-thread (to append artical)
for artical in articals {
// print (articles) THIS IS WOKING WELL
self.myArray.append(artical)
}
DispatchQueue.main.async {
self.articalsTableView.reloadData()
}

Swift error Trying to Pass Array to Another Class

So I am probably doing this all wrong but I want to make a shopping list app and I have two view controllers, one with the list and one with a textbook and button to add to the list but I can't figure out how to get the array to the other class. I have this code so far and the error I get is
Instance member 'list' cannot be used in type 'mainViewController'
And this is my code
import UIKit
class mainViewController: UIViewController {
var list:[String] = [""]
#IBOutlet weak var item: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboardWhenTappedAround()
// Do any additional setup after loading the view.
}
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(mainViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
func dismissKeyboard() {
view.endEditing(true)
}
#IBAction func AddToList(sender: UIButton) {
list.append(item.text!)
}
static func getList(inout Array: [String]) -> [String] {
return list
}
}
Any help much appreciated, please keep it positive though and keep in mind I am very new to this forum and swift. Thanks!
The error message is very clear that you are trying to access an instance field in type context (without instance).
To fix it, just remove static in getList function.
PS: Please follow Swift naming conventions to capitalize your class name

(Swift) How to create global array?

I am trying to create a global array (of items in a cart) in Swift so that I can access it from different pages.
Can you please point me in the right direction? declaring an array under the import statement in AppDelegate gives me the "unresolved Identifier" issue.
What should I use? How can I accomplish that? Thank you!
In swift you can encapsulate variables in a struct and you can access them anywhere.
struct GlobalVariables {
static var globalString = "MyString"
}
To call it
// Get value
let str = GlobalVariables.globalString
// Set value
GlobalVariables.globalString = "New value"
Checkout the reference for more information.
first controller: declare variable
import UIKit
class ViewController: UIViewController {
var test2 = 5
override func viewDidLoad() {
super.viewDidLoad()
}
}
second controller call variable
class ViewController1: UIViewController {
var myCustomViewController: ViewController = ViewController()
override func viewDidLoad() {
super.viewDidLoad()
print(myCustomViewController.test2)
} }

Resources