Swift 3 - Passing data between a View Controller and after that to another 2
Before calling presentViewController
add :
nextViewController.name = yourTextField.text
You could also delete the segue
call. That is redundant.
Here is an example that I've used in the past :
@IBAction func doSegue(_ sender: UIButton) {
buttonTag = sender.tag
let storyboard = UIStoryboard (name: "Main", bundle: nil)
let resultVC = storyboard.instantiateViewController(withIdentifier: "ResultViewController")as! ResultViewController
// Communicate with new VC - These values are stored in the destination
// you can set any value stored in the destination VC here
resultVC.firstValue = buttonTag
resultVC.secondValue = randomOpponentValue()
self.navigationController?.pushViewController(resultVC, animated: true)
}
How to organize data shared between view controllers in swift
The approach you mentioned where you have a base view controller, is not a suitable one here and also deriving from it will create problems like duplicating the data and also potentially cause issues if you want to access data elsewhere from a non view controller.
You will need to have a model layer that will enable a controlled access to your model (data) objects. For instance, you can think of a model class say ChoiceManager and make it a Singleton.
class ChoiceManager{
//The singleton instance
static let sharedInstance = ChoiceManager()
var choices : [Choices] = []
//Logic to create Choice objects - may be parsing from a JSON, or from a network etc
}
Now across your project, you can access to the same ChoiceManager, by just saying
ChoiceManager.sharedInstance
And also access choices:
ChoiceManager.sharedInstance.choices
how to properly share a variable among some view controllers in swift?
I would recommend avoiding singletons here as well. The primary motivation is to make things testable. Here's a possible approach.
You have a User
something like this:
struct User {
let userid: String
let email: String
}
Declare a protocol for managing your user. Using a protocol makes testing easier since you can create a mock that conforms to it.
protocol UserManagerProtocol {
func getSignedInUser() -> User?
func signIn(userid: String, password: String) -> User?
}
Declare your actual class that implements the protocol:
class UserManager: UserManagerProtocol {
fileprivate var signedInUser: User?
func getSignedInUser() -> User? {
return signedInUser
}
func signIn(userid: String, password: String) -> User? {
//call your server to sign in user
// if sign in fails, return nil
// if sign in works, create a User object
signedInUser = User(userid: userid, email: "email retrieved from server")
return signedInUser
}
}
Add a reference in your view controllers, but declare it using the protocol, not the actual class. Again, this allows for mocking.
class HomeVC: UIViewController {
var userManager: UserManagerProtocol?
}
class PostVC: UIViewController {
var userManager: UserManagerProtocol?
}
Finally, in your AppDelegate, when you launch the app, create a single instance of your UserManager
, store it in the AppDelegate, and pass it to all your view controllers. In this example, I've obviously left out a lot of stuff because I don't know what your AppDelegate looks like.
class AppDelegate: NSObject, UIApplicationDelegate {
var userManager: UserManagerProtocol?
func applicationDidFinishLaunching(_ application: UIApplication) {
userManager = UserManager()
//when setting up your tab bar controllers, pass the userManager instance to each of them
}
}
passing data between view controllers without changing views
In your case, don't pass data.
Create a shared object to act as your data model. When users fill in the fields, update the data model.
When the user moves to the second controller/view, that controller uses the data model object to show what it needs to.
class FakeVC1 {
func userInput() {
DataModel.shared.username = "Me"
}
}
class FakeVC2 {
func viewAppears() {
if let name = DataModel.shared.username {
print(name)
} else {
print("I have nothing to say")
}
}
}
class DataModel {
static let shared = DataModel()
var username: String?
}
FakeVC1().userInput()
FakeVC2().viewAppears()
Getting data from another view controller (not via passing the data forward or backward) in Swift 4
Create a singleton class. let's say DataManager.
class DataManager: NSObject {
// A Singleton instance
static let shared = DataManager()
// your array
var dataArray = [String]()
}
now access this array from anywhere in the app.
Print(DataManager.shared.dataArray)
Related Topics
How to Programmatically Scroll Through a Collection View
Send and Receive Messages Through Nsnotificationcenter in Objective-C
Check For Internet Connection With Swift
Bold & Non-Bold Text in a Single Uilabel
Seeing Black Bars At the Top and Bottom of the Iphone X Simulator
Setting Action For Back Button in Navigation Controller
Eliminate Extra Separators Below Uitableview
How to Enable File Sharing For My App
How to Open Phone Settings When a Button Is Clicked
How to Show "Done" Button on iOS Number Pad Keyboard
How to Debug Memory Leaks When Leaks Instrument Does Not Show Them
Figure Out Size of Uilabel Based on String in Swift
Fatal Error: Unexpectedly Found Nil While Unwrapping an Optional Values
Generate Json String from Nsdictionary in Ios
How to Have Stored Properties in Swift, the Same Way I Had on Objective-C