Passing value while instantiating the view - swift

Need to adding a value from one view controller to another view controller via the following way. I successfully able to move to the another page but not able to passing the value
sideMenuController?.cache(viewControllerGenerator: {
self.storyboard?.instantiateViewController(withIdentifier: "projectDetailController")
}, with: "333")
sideMenuController?.delegate = self as? SideMenuControllerDelegate
sideMenuController?.setContentViewController(with: "333", animated: Preferences.shared.enableTransitionAnimation)
sideMenuController?.hideMenu()

Add a property inside ProjectDetailController:
class ProjectDetailController: UIViewController {
var someValue: String?
/* more code */
}
Move the ProjectDetailController creation above and, once created - try to inject the value you want:
let projectDetailController = self.storyboard?.instantiateViewController(withIdentifier: "projectDetailController") as! UINavigationController
let projectDetailViewController = projectDetailController.viewControllers.first as! ProjectDetailViewController
projectDetailViewController.projectId = id
sideMenuController?.cache(viewControllerGenerator: { projectDetailController }, with: "333")
sideMenuController?.delegate = self as? SideMenuControllerDelegate
sideMenuController?.setContentViewController(with: "333", animated:
Preferences.shared.enableTransitionAnimation)
sideMenuController?.hideMenu()

Related

Return value in DropDownMenu on selection?

I'm new to Xcode and Swift. I am using this library: https://github.com/PhamBaTho/BTNavigationDropdownMenu to create DropDownMenu in my app. I followed the demo from Github and everything works fine. I am trying to get the selected value and assign it to a string outside didSelectItemAtIndexHandler function. This is my code:
var menuView: BTNavigationDropdownMenu!
var items = ["San Francisco", "New York", "LA", "Chicago"]
menuView = BTNavigationDropdownMenu(navigationController: self.navigationController, containerView: self.navigationController!.view, title: BTTitle.index(0), items: items)
menuView.didSelectItemAtIndexHandler = {(indexPath: Int) -> Void in
self. myCity = items[indexPath]
//print(myCity) // prints the correct city every time
}
self.navigationItem.titleView = menuView
I am trying to get the following outside menuView.didSelectItemAtIndexHandler :
var test = String()
test = myCity
print(test)
Any help will be appreciated. Thanks in advance!
I am trying to pass the data from here to TopFiveViewController.
menuView.didSelectItemAtIndexHandler = {(indexPath: Int) -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let vc = storyboard.instantiateViewController(withIdentifier: "TopFiveViewController") as! TopFiveViewController
vc.myCity = self!.items[indexPath]
print(myCity) // prints the correct city every time but it doesn't pass the value to TopFiveViewController!
}
In the TopFiveViewController I have:
var myCity = String()
override func viewDidLoad() {
super.viewDidLoad()
if self.myCity == "San Francisco" {
// load SF json file
} else if myCity == "New York" {
// load NY json file
}
As you mentioned that everything is happening in your viewDidLoad() I think it's important to understand what is happening.
The view loads and test as well as myCity are set to nil.
When the user selects an item from the dropdown menu the code within menuView.didSelectItemAtIndexHandler will be called and myCity will now be set to the selected value although test will still be nil as the completion handler setting the value of myCity has no effect on test.
You should execute whatever code you want to execute when the value is selected within the completion handler (where self. myCity = items[indexPath] is located).

How do I reference a variable (a picker view value) from one view controller in another view controller?

I am trying to take these variables from one of my view controller's swift file:
//global
let choice1Box1 = drivingGear[chooseDrivingGear.selectedRow(inComponent: 0)]
let choice2Box1 = drivingGear[chooseDrivenGear1.selectedRow(inComponent: 0)]
This is whats being done to the variables in the original class:
#IBAction func showResultBox1(_ sender: Any) {
let choice1Box1 = self.drivingGear[self.chooseDrivingGear.selectedRow(inComponent: 0)]
let choice2Box1 = self.drivingGear[self.chooseDrivenGear1.selectedRow(inComponent: 0)]
if let intVal1 = Double(choice1Box1), let intVal2 = Double(choice2Box1) {
result = intVal2 / intVal1
let newLabel = String(result)
resultBox1.setTitle(newLabel, for: .normal)
}
}
Just do like this:
Once you have picked the value from the pickerView. Pass it like this.
For Eg. You need to pass a String to next VC:
In SecondVC: Declare a value at top like this:
var strFromPreviousVC:String = String()
In First VC: Send the Value like this:
let objSecondVC = self.storyboard?.instantiateViewController(withIdentifier: "secondVC") as! SecondVC
objSecondVC.strFromPreviousVC = "your selected String here"
self.navigationController?.pushViewController(objSecondVC, animated: true)
And yes its done, it will be passed to SecondVc and you can use the value like print(strFromPreviousVC) in SecondVc
Hope it helps.

How to pass array values from Protocol of a ViewController to another ViewController

Explanation of what I want to do:
I want to Create a let params : [String: AnyObject] Array/Dic that holds [ name
: nameTextField.text, pass : passTextField.text, etc... ] in one
ViewController called "SignUpVC"
Also inside "SignUpVC" I want a protocol to hold my values for
params and "save" them for later use in other ViewControllers. Without using NSUserDefaults.
Now with those params being saved and assigned to the protocol's
function's parameters, I want to go into another ViewController called
"SchoolSelectionVC" and bring up those values and assign the
params to a var newParams : [String : AnyObject] so they equal the same thing but ill be able to change some of the values if
I wanted to...
So basically, I am trying to assign some values with the user input from SignUpVC, save those values, and bring them over to another variable in another ViewController for further use or change.
Problem:
Below is my code, and it shows that i am creating a SignUpVC protocol, a delegate called "var signupDelegate = SignUpVCProtocol", a let param, assigning it values, trying to assign the let param to the SignUpVC Protocol parameters, then move into another ViewController ("SchoolSelectionVC"), but the error stops it there. This all happens inside a button click action inside SignUpVC.
I just want to know why the delegate variable holding the SignUpVCProtocol and its function is giving me an error when I try passing the parameters to it.
If there are any tips on how to save values from one VC to another, let me know and if any of my code needs more explanation let me know too!
Code:
protocol SignUpVCProtocol {
func logInData(params : [String : AnyObject])
}
class SignUpVC: UIViewController{
//MARK:- #IBOutlet
//MARK: ^^^^^^^^^^^^^^^^^^^^
#IBOutlet var signUpWithFacebookButton: UIButton!
//MARK:- Properties
//MARK: ^^^^^^^^^^^^^^^^^^^^
var selectedTextField : UITextField!
var keyboardPresent = false
var loginFlag = false
var fbId: String!
var picUrl: String!
var schoolID : String = ""
var schoolDict : [String:AnyObject]!
var player: AVPlayer?
var fbData : AnyObject!
let domainLbl = UILabel()
var signUpDelegate : SignUpVCProtocol! //Delegate var for Protocol
Inside a Button Action:
let params = [
"Action" : "signUp" as AnyObject,
"name" : self.nameTextField.text! as AnyObject,
"email" : "\(self.emailTextField.text!)" as AnyObject,
"password" : self.passwordTextField.text! as AnyObject,
"school" : self.schoolTextField.text! as AnyObject,
"device_token" : sharedAppdelegate.DeviceToken as AnyObject,
"device_type" : "iphone" as AnyObject,
"school_id" : self.schoolID as AnyObject
]
self.signUpDelegate.logInData(params: params) //!!Where i want to assign the above params to the protocol params for use in SchoolSelectionVC
//ERROR HAPPENS RIGHT ABOVE^^
let schoolVC = self.storyboard?.instantiateViewController(withIdentifier: "SchoolSelectionVC") as! SchoolSelectionVC
let navVC = UINavigationController(rootViewController: schoolVC)
navVC.isNavigationBarHidden = true
schoolVC.delegate = self
self.present(navVC, animated: true, completion: nil)
//in another VC Class
extension SchoolSelectionVC: SignUpVCProtocol
{
func logInData(params: [String : AnyObject]) {
self.newParams = params as! [String : String]
}
}
Don't use protocols to pass data between viewControllers, use
func prepare(for segue: UIStoryboardSegue, sender: Any?)
instead.
Check this answer:
Passing object with prepareForSegue Swift
For viewControllers you need to load programmatically you can use this example of passing data:
//For using without navigation controller
let vc = SomeViewController(nibName: "SomeViewController", bundle: nil);
vc.someVariable = someData
self.present(vc, animated: true, completion: nil)
//For using with navigation controller
let vc = SomeViewController(nibName: "SoveViewController", bundle: nil);
vc.someVariable = someData
self.navigationController?.pushViewController(vc, animated: true)

My cells are duplicating themselves

I am new to swift and I am trying to make this note app. I have split view controller that goes in my first view controller and that view controller connects to a table view controller. Everything works perfectly is just that when I launch the app I have all the notes like I want but when I try to go back to my first view controller and come back to my table view controller, all the notes are duplicated every single time I do it. I tried everything I can try, is there anyone who can help me
my MasterViewController is
import UIKit
class MasterViewController: UITableViewController {
var detailViewController: DetailViewController? = nil
override func viewDidLoad()
{
super.viewDidLoad()
Note.loadNotes() // The problem is here, I think
noteTable = self.tableView
// Do any additional setup after loading the view, typically from a nib.
let addButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(insertNewObject(_:)))
navigationItem.rightBarButtonItem = addButton
if let split = splitViewController
{
let controllers = split.viewControllers
detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
}
}
My loadNotes function is
class func loadNotes()
{
let defaults:UserDefaults = UserDefaults.standard
let saveData: [NSDictionary]? = defaults.object(forKey: kAllNotes) as? [NSDictionary]
if let data:[NSDictionary] = saveData
{
for i:Int in 0 ..< data.count
{
let n:Note = Note()
n.setValuesForKeys(data[i] as! [String : Any])
allNotes.append(n)
}
}
}
Your loadNotes method keeps appending. The first line of loadNotes should be:
allNotes = [Note]()
Then it starts with an empty array and fills it up.
And why is loadNotes a static method? That's a bad design. Make Notes a normal class and make loadNotes an instance method.
On an unrelated note (no pun intended), do not use UserDefaults to store app data. Only use it to store little bits of information.

Pass object from tableview to destination with revealviewcontroller in between

I am trying to pass an object from my tableview to the detail view. I am using the revealviewcontroller framework to have a slide out menu. Therefore I need to create a segue from the tableview to the revealviewcontroller and from here another one to the final detailviewcontroller.
That is why I canĀ“t set the object in the detail view - any idea how to do so?
This is the used code:
if segue.identifier == "communityDetailSegue" {
// Get the cell that generated this segue.
if let selectedCommunityCell = sender as ? UITableViewCell {
let destination = segue.destinationViewController as!CommunityViewController
if let communityIndex = self.tableView.indexPathForCell(selectedCommunityCell) {
destination.community = self.communitiesOfCurrentUser[communityIndex.row]
print(self.communitiesOfCurrentUser[communityIndex.row].name)
}
}
}
And this is the exception.
Could not cast value of type 'SWRevealViewController' (0x10027b9f0) to 'CommunityViewController'
You get the error because the segue's destination VC is the SWRevealViewController and not the CommunityViewController.
One way of solving your problem would be to pass the value in two steps:
First, in prepareForSegue() you pass the value to the SWRevealViewController (you'll need a subclass for this one, e.g. MyRevealViewController):
if segue.identifier == "communityDetailSegue" {
// Get the cell that generated this segue.
if let selectedCommunityCell = sender as ? UITableViewCell {
let destination = segue.destinationViewController as! MyRevealViewController
if let communityIndex = self.tableView.indexPathForCell(selectedCommunityCell) {
destination.community = self.communitiesOfCurrentUser[communityIndex.row]
print(self.communitiesOfCurrentUser[communityIndex.row].name)
}
}
}
Then, in MyRevealViewControlleryou can pass the value as soon as it is set:
class MyRevealViewController : SWRevealViewController {
// Let's assume this is the outlet to your final VC:
IBOutlet let communityViewController: CommunityViewController!
var community: YourCommunityType {
didSet {
if let communityVC = self.communityViewController {
communityVC.community = self.community
}
}
}
}