How to: User Add/Remove from array in other ViewController? - ios

I have an empty userArray in viewController1 that will use Strings.
In a popup, viewController2, I want to have the possibility for the user to add or remove from this userArray.
I'm gonna use a textField for the user to add their string but what is an easy way for the user to see the contents of the array and remove from it?
How do I pass this data between the viewControllers, whilst making sure it gets saved, and what would you recommend me using for removing from the array?

Assuming you have a segue from viewController1 to viewController2, you can use segue.destination and set the segue.destination.userArray property to whatever you want.
If you don't have a segue, and what you are trying to do is have a model shared between view controllers, one thing you can do is make another class with a static property userArray and access it that way.
As for array removal, see https://developer.apple.com/documentation/swift/array/1641390-remove

Write your Array outside of your ViewController Class. Then you can access it from other ViewControllers.
Example:
//ViewController1.swift
import UIKit
var userArray = [String]()
class ViewController1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
//ViewController2.swift
import UIKit
class ViewController2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
userArray.append("A")
userArray.append("B")
userArray.remove(at: 0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Related

Storing input from field as variable with swift 3

I realize this question has been asked numerous times before, but I can't quite get the solutions to work, even by just copying and pasting them, and suspect that most swift documentation spans the three versions since swift's release.
I'm attempting to do something as simple as storing a variable from a field input and not having much luck.
import UIKit
class ViewController: UIViewController {
#IBOutlet var userNumber: UILabel!
#IBOutlet var userField: UITextField!
#IBAction func userButton(_ sender: UIButton) {
let userInput = userField.text
//some action
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You should check whether you have set your textfield's delegate with respect to parent view controller.
Go to storyboard.
Select textfield.
Right click on it.
set delegate from textfield to view controller

Swift - Set a UI element from outside

I have this UIViewController
import UIKit
class UIViewController1: UIViewController {
#IBOutlet weak var someTitle: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
And I am trying to set someTitle when I instantiate it from another view controller:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(animated: Bool) {
let stb = UIStoryboard(name: "Main", bundle: nil)
let vc1 = stb.instantiateViewControllerWithIdentifier("someSTBID") as! UIViewController1
vc1.someTitle.text = "My Title" // it fails here!!!!!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The reason it fails at the line above is that I was trying to force unwrapping a nil optional, which is someTitle.
Please show me a way to set someTitle in this situation.
Your second UIViewController hasn't been loaded yet, so the someTitle IBOutlet will be nil. You got two options:
The easy one: you force the load of the second UIViewController, for example: vc1.view is enough and then you set it (I don't recommend this)
The proper one: you let the second UIViewController be responsible for setting its own title at the right time. If you need to pass the "My title", you can simply pass it via a function like configureVc(title: String), or by exposing a variable like var title: String, so on viewDidLoad of the second UIViewController you would someTitle.text = title.
Do you need it to go into the superclass viewDidAppear, because it should work if you put it into the superclass viewDidLoad(). I hope that helps you and future viewers.

IOS Swift - Passing data between view controllers using container view

I am a little confused on how to use container views correctly, i will try to explain it the best i can.
I have a main view controller that has an animation function.
import UIKit
class MainViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {
// Run view setups
override func viewDidLoad() {
super.viewDidLoad()
}
func closePicker(){
self.view.layoutIfNeeded();
UIView.animateWithDuration(0.5, animations: {
self.countryPickerConst.constant = -206;
self.view.layoutIfNeeded();
})
}
}
In interface builder i have added a container view with a new view controller that contains a button like so:
import UIKit
class ContainerViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func runAnimation(sender: UIButton) {
//I want to call the function in my other view controller
}
}
In the action runAnimation i want to call the function in the MainViewController. If i just create an instance of MainViewController and call the function it seems to loose its 'self' relevance.
If someone could explain to me the best practice for doing things like this that would be great.
Thanks
From your explanation MainViewController is the parent of ContainerViewController so to access closePicker from ContainerViewController you would do:
#IBAction func runAnimation(sender: UIButton) {
(self.parentViewController as! MainViewController).closePicker()
}

Access array data from another view controller

In TerningspilletSpillereViewController I have an array that looks like this:
var mineSpillere = ["1SP", "2SP", "3SP"]
and this under:
func assignArray() {
let obj = TerningspilletViewController()
obj.mineSpillere2 = self.mineSpillere
}
In my other UIViewController (TerningspilletViewController) I have this
var mineSpillere2 = [String]()
I want to generate a random (1SP, 2SP or 3SP) on button click like this from a function:
func generateNumber() {
let array = aBB
let randomIndex = Int(arc4random_uniform(UInt32(array.count)))
randomLabel.text = (array[randomIndex])
}
But this gives me the following error:
fatal error: Array index out of range.
I this line randomLabel.text = (array[randomIndex])
Why is that?
See this example and update for your usage. I'm not quite understanding your naming but this is how you can get the data from a different view controller (that is initialized with the data).
First View Controller:
import UIKit
class ViewController: UIViewController {
var arrayWithoutData = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
assignArray()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func assignArray() {
let otherVC = NextViewController()
arrayWithoutData = otherVC.mineSpillere
println(arrayWithoutData)
}
}
Second View Controller:
import UIKit
class NextViewController: UIViewController {
var mineSpillere = ["1SP","2SP","3SP"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
That error could occur for two reasons:
The array length changes between the call to array.count and the array access. This could only happen if you assign or modify the array from another thread
The array is empty, in which case arc4random_uniform can never produce a number 0<=X<0 (and whatever it returns will trigger an index-out-of-bounds exception).
So if you are not using multiple threads, check if the array is empty.

how to acces a variable in another class and change its value

I am new to Xcode and Swift so I don't know much about how it all works, but I am trying to make a pop-up view. I want a small view to pop up when I click a button. The view is a View Container (I don't know if that is the best way to do this so if not please tell me a better way to do this) and it starts out hidden then when I click a button it becomes visible. This View Container also has a button that if clicked, it will make the view hidden again.
Here is the code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var popUpView: UIView!
#IBAction func startButton(sender: UIButton) {
popUpView.hidden = false
}
}
import UIKit
class PopUpViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue:UIStoryboardSegue,
sender:AnyObject?)
{
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
#IBAction func backButton(sender: UIButton) {
ViewController().popUpView.hidden = true
}
}
When I run the app it starts fine because the start button is there and when I click it the pop up shows up but when I click the back button it gives me an error which says that in the console
Unknown class MKMapView in Interface Builder file.
fatal error: unexpectedly found nil while unwrapping an Optional value
and in line 31 ViewControler().popUpView.hidden = true
it says Thread 1: EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode=0x0)
Can someone help. Thanks
Access popUpView variable from didPrepareForSeque method (this method gets called automatically when you segue to another view). Problem is that if you try to set value to soon (meaning, that button is not drawn on view), you will get nil error. Here is a little workaround. You use temporary variable (tmpValue) to store state of your button (to be hidden or not), so when viewDidLoad, you method will read this value and set button to hidden state as you intended.
In ViewController class declare temporary variable (must be optional):
var tmpValu:Bool?
Then in your PopUpViewController class remove this line from backButton action:
ViewController().popUpView.hidden = true
Instead, you will use prepareForSegue method, like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destinationViewController = segue.destinationViewController as! ViewController
destinationViewController.tmpValu = true
}
Now, back in ViewController class in viewDidLoad add this code:
override func viewDidLoad() {
super.viewDidLoad()
if let value = tmpValu {
popUpView.hidden = value
}
}

Resources