Show ViewController programmatically (not working) - swift

I got a main VC called "ViewController.swift", which is bond to my ViewController Scene in Main.storyboard.
Then I want another screen, which shows when a condition in my ViewController.swift is fulfilled.
Therefore I got a Gameover.storyboard, which has a VC Scene with Storyboard ID "overID" as well as a "GameoverViewController.swift" to handle the GameOver Scene.
Here is my code in ViewController.swift, which should open Gameover.storyboards VC Scene when the condition you see below is fulfilled:
import UIKit
class ViewController: UIViewController {
var wantedLiter = 10.00
var timer : Timer?
var actualLiter = 0.00
var timerReset = true
var preisProLiter = 1.26
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
let storyBoard: UIStoryboard = UIStoryboard(name: "Gameover", bundle: nil)
let gameoverViewController = storyBoard.instantiateViewController(withIdentifier: "overID") as! GameoverViewController
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#IBOutlet weak var preisliterLabel: UILabel!
#IBOutlet weak var euroLabel: UILabel!
#IBOutlet weak var numberLabel: UILabel!
#IBOutlet weak var numberButton: UIButton!
#IBOutlet weak var confirmButton: UIButton!
#IBAction func confirm(_ sender: Any) {
}
override func viewDidLoad() {
super.viewDidLoad()
numberLabel.text = String(round(1000*actualLiter)/1000) //initial value
preisliterLabel.text = String(preisProLiter)
// Do any additional setup after loading the view.
}
#IBAction func holdingTheButton(_ sender: Any) {
print("I am holding")
timerReset = false // reset to false since you are holding the button
guard timer == nil else { return }
timer = Timer.scheduledTimer(timeInterval: 0.005, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
}
#IBAction func buttonReleased(_ sender: Any) {
print("button released")
if (wantedLiter == actualLiter){
print("WIN!")
actualLiter = 0;
}
//startTime = 0.00
timer?.invalidate()
timer = nil
// timerReset = true // reset to true since you released.
}
#objc func updateTime(){
//update label every second
print("updating label ")
if (wantedLiter <= actualLiter){
print("Ooops")
actualLiter = 0;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
self.present(gameoverViewController, animated: true, completion: nil)
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
}
actualLiter += 0.01
numberLabel.text = String(round(1000*actualLiter)/1000)
euroLabel.text = String((round(100*actualLiter*preisProLiter)/100))
}
}
And now got you some Screenshots, which might help.
If you need more Screens, please ask.
Right now, I got following errors:
1) ViewController.swift in the upper part marked with "!!!!..."
Cannot use instance member 'storyBoard' within property initializer; property initializers run before 'self' is available
2) ViewController.swift
Cannot convert value of type 'gameoverViewController.Type' to expected argument type 'UIViewController'
3) ViewController.swift upper Part:
Use of undeclared type 'GameoverViewController'
This is how I changed the code:
import UIKit
class ViewController: UIViewController {
var wantedLiter = 10.00
var timer : Timer?
var actualLiter = 0.00
var timerReset = true
var preisProLiter = 1.26
let storyBoard: UIStoryboard = UIStoryboard(name: "Gameover", bundle: nil)
var gameoverViewController: GameoverViewController!
#IBOutlet weak var preisliterLabel: UILabel!
#IBOutlet weak var euroLabel: UILabel!
#IBOutlet weak var numberLabel: UILabel!
#IBOutlet weak var numberButton: UIButton!
#IBOutlet weak var confirmButton: UIButton!
#IBAction func confirm(_ sender: Any) {
}
override func viewDidLoad() {
super.viewDidLoad()
gameoverViewController = storyBoard.instantiateViewController(withIdentifier: "overID") as? GameoverViewController
numberLabel.text = String(round(1000*actualLiter)/1000) //initial value
preisliterLabel.text = String(preisProLiter)
// Do any additional setup after loading the view.
}
#IBAction func holdingTheButton(_ sender: Any) {
print("I am holding")
timerReset = false // reset to false since you are holding the button
guard timer == nil else { return }
timer = Timer.scheduledTimer(timeInterval: 0.005, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
}
#IBAction func buttonReleased(_ sender: Any) {
print("button released")
if (wantedLiter == actualLiter){
print("WIN!")
actualLiter = 0;
}
//startTime = 0.00
timer?.invalidate()
timer = nil
// timerReset = true // reset to true since you released.
}
#objc func updateTime(){
//update label every second
print("updating label ")
if (wantedLiter <= actualLiter){
print("Ooops")
actualLiter = 0;
self.present(gameoverViewController as! UIViewController, animated: true, completion: nil)
}
actualLiter += 0.01
numberLabel.text = String(round(1000*actualLiter)/1000)
euroLabel.text = String((round(100*actualLiter*preisProLiter)/100))
}
}
(not working)
And I changed the GameoverViewController type to UIViewController.
But where was my Typo?? (G instead of g)?

Move the initializer for gameoverViewController into viewDidLoad or the like and make gameoverViewController an optional or implicitly unwrapped optional (that's the ! after a type)
Should be fixed by 1.
Please show the source for GameoverViewController if this is not fixed by 1. too.

Related

Force unwrapping nil optional for UIImageView when transitioning to view controller

I'm running into an error when transitioning to view controllers by overriding the built-in prepare() function in Swift. I have a UIImageView for backgrounds on my screens. Here is the code for two of the view controllers in question.
import UIKit
import FirebaseAuth
class HomeVC: UIViewController {
#IBOutlet weak var signOutButton: UIButton!
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var friendsNavButton: UIButton!
#IBOutlet weak var homeNavButton: UIButton!
#IBOutlet weak var profileNavButton: UIButton!
#IBOutlet weak var bumpButton: UIButton!
#IBOutlet weak var welcomeLabel: UILabel!
#IBOutlet weak var doNotDisturbLabel: UILabel!
#IBOutlet weak var doNotDisturbButton: UIButton!
var userName = ""
var dndIsOn: Bool = false
#IBAction func dndToggled(_ sender: Any) {
dndIsOn = !dndIsOn
User.current.available = !dndIsOn
FirestoreService.db.collection(Constants.Firestore.Collections.users).document(User.current.uid).updateData([Constants.Firestore.Keys.available : !dndIsOn])
if dndIsOn {
print("DND is on!")
setupDNDUI()
} else if !dndIsOn {
print("DND is off!")
setupActiveUI()
}
}
#IBAction func signOutTapped(_ sender: Any) {
let firAuth = Auth.auth()
do {
try firAuth.signOut()
} catch let signOutError as NSError {
print ("Error signing out: %#", signOutError)
}
print("Successfully signed out")
}
#IBAction func bumpTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toCall, sender: self)
}
#IBAction func friendsNavTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toFriends, sender: self)
}
#IBAction func profileNavTapped(_ sender: Any) {
let nav = self.navigationController //grab an instance of the current navigationController
DispatchQueue.main.async { //make sure all UI updates are on the main thread.
nav?.view.layer.add(CATransition().segueFromLeft(), forKey: nil)
nav?.pushViewController(ProfileVC(), animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(true, animated: true)
self.backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill
doNotDisturbLabel.isHidden = true
if !userName.isEmpty {
welcomeLabel.text = "Welcome Back, " + userName + "!"
} else {
welcomeLabel.text = ""
}
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .darkContent
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let friendsVC = segue.destination as? FriendsVC else {
return
}
FirestoreService.db.collection(Constants.Firestore.Collections.users).document(User.current.uid).getDocument { (snapshot, err) in
if let err = err {
print(err.localizedDescription)
} else {
let data = snapshot!.data()!
let requests = data[Constants.Firestore.Keys.requests] as? [String]
if let requests = requests {
friendsVC.requests = requests
}
}
}
}
class FriendsVC: UIViewController {
//var friends: [Friend] = User.current.friends
var friends: [User] = []
var requests: [String]?
#IBOutlet weak var requestsNumberLabel: UILabel!
#IBOutlet weak var backgroundImageView: UIImageView!
#IBOutlet weak var friendRequestsButton: UIButton!
#IBOutlet weak var homeNavButton: UIButton!
#IBOutlet weak var friendsTitle: UILabel!
#IBOutlet weak var friendTableView: UITableView!
#IBOutlet weak var addFriendButton: UIButton!
#IBOutlet weak var tableViewTopConstraint: NSLayoutConstraint!
#IBAction func friendRequestsTapped(_ sender: Any) {
self.performSegue(withIdentifier: Constants.Segues.toRequests, sender: self)
}
#IBAction func homeNavTapped(_ sender: Any) {
let nav = self.navigationController //grab an instance of the current navigationController
DispatchQueue.main.async { //make sure all UI updates are on the main thread.
nav?.view.layer.add(CATransition().segueFromLeft(), forKey: nil)
nav?.pushViewController(HomeVC(), animated: false)
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.setNavigationBarHidden(true, animated: true)
backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill
friendTableView.backgroundView?.backgroundColor = .white
friendsTitle.isHidden = false
UserService.getUserArray(uids: User.current.friendUids, completion: { (users) in
guard let users = users else {
print("User has no friends")
return
}
self.friends = users
self.friendTableView.reloadData()
})
guard let requests = self.requests else {
friendRequestsButton.isHidden = true
requestsNumberLabel.isHidden = true
self.tableViewTopConstraint.constant = 0
return
}
requestsNumberLabel.text = requests.count.description
// Do any additional setup after loading the view.
friendTableView.delegate = self
friendTableView.dataSource = self
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let homeVC = segue.destination as? HomeVC {
homeVC.userName = User.current.firstName
} else if let requestsVC = segue.destination as? RequestsVC {
UserService.getUserArray(uids: self.requests!) { (requesters) in
if let requesters = requesters {
requestsVC.requesters = requesters
}
}
}
}
}
When my app loads into the home screen, there is no problem, and when a button is tapped to transition to FriendsVC, there is no problem. However, when I try to initiate the transition from HomeVC to ProfileVC or from FriendVC to HomeVC, I get the error: "Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value" at the self.backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFill lines in my viewDidLoad methods. These segues have something in common in that these are the ones where I override the prepare() function, but I'm not sure what I'm doing wrong

Sigbart error during prepare for segue/unwind segue

I have an app where it is a marketplace and when you click on a product, it opens a detail view controller passing the data to display on the DetailVC. Additionally, inside the DetailVC, if you click on a button to claim the product, it segues to another VC to finalize the transaction.
In the DetailVC, there is a back button which is an unwind segue back to the main marketplace VC. Inside the TransactionVC, there is a cancel button which takes you back to the DetailVC.
When I am clicking the backButton in the DetailVC to take me back to the main market VC but I am getting a SIGBART Error and this :
020-07-15 09:05:23.707490-0500 evolutionatx[707:141952] Could not cast value of type 'evolutionatx.MarketplaceViewController' (0x1032c7868) to 'evolutionatx.PopUpPurchaseViewController' (0x1032c7ba8).
Here is the code for the DetailVC
import UIKit
import iCarousel
import CoreData
class MarketDetailViewController: UIViewController, UIScrollViewDelegate, iCarouselDelegate, iCarouselDataSource {
var productImageArray = [UIImage]()
var productVideo = String()
var pointsToPurchase = String()
var productName = String()
var productDescription = String()
var companyLogo = UIImage()
var companyWebsite = String()
var additionalProductImage = [UIImage]()
var companyName = String()
var promoCODE = String()
var buyLink = String()
var slides:[Slide] = [];
//IB
#IBOutlet weak var productNameLabel: UILabel!
#IBOutlet weak var productPriceLabel: UILabel!
#IBOutlet weak var productDescLabel: UILabel!
#IBOutlet weak var claimButton: UIButton!
#IBOutlet weak var imgScrollView: UIScrollView!
#IBOutlet weak var websiteButton: UIButton!
#IBOutlet weak var pageControl: UIPageControl!
#IBOutlet weak var logoDisplay: UIImageView!
#IBOutlet weak var carouselView: iCarousel!
#IBOutlet weak var otherProductslabe: UILabel!
var carouselImages = [UIImage]()
var evoCoin = Int()
override func awakeFromNib() {
super.awakeFromNib()
carouselImages = productImageArray
}
override func viewDidLoad() {
super.viewDidLoad()
valueSetter()
imgScrollView.delegate = self
slides = createSlides()
setupSlideScrollView(slides: slides)
pageControl.numberOfPages = slides.count
pageControl.currentPage = 0
view.bringSubviewToFront(pageControl)
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageControl.currentPage = Int(pageIndex)
let maximumHorizontalOffset: CGFloat = scrollView.contentSize.width - scrollView.frame.width
let currentHorizontalOffset: CGFloat = scrollView.contentOffset.x
// vertical
let maximumVerticalOffset: CGFloat = scrollView.contentSize.height - scrollView.frame.height
let currentVerticalOffset: CGFloat = scrollView.contentOffset.y
let percentageHorizontalOffset: CGFloat = currentHorizontalOffset / maximumHorizontalOffset
let percentageVerticalOffset: CGFloat = currentVerticalOffset / maximumVerticalOffset
}
#IBAction func claimProduct(_ sender: Any) {
print("tap rec")
claimProductandPurchase()
}
func claimProductandPurchase(){
evoCOiner()
if(evoCoin >= Int(pointsToPurchase)!){
print("Transaction Successful")
performSegue(withIdentifier: "proceedQuestion", sender: self)
}
else{
showToast(controller: self, message: "Insufficient EvoCoins", seconds: 0.5)
}
}
func showToast(controller: UIViewController, message : String, seconds: Double) {
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
alert.view.backgroundColor = UIColor.black
alert.view.alpha = 0.6
alert.view.layer.cornerRadius = 15
controller.present(alert, animated: true)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + seconds) {
alert.dismiss(animated: true)
}
}
func evoCoiner(){
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "EvoCoins")
request.returnsObjectsAsFaults = false
do{
let result = try context.fetch(request)
for data in result as! [NSManagedObject]
{
evoCoin = data.value(forKey: "evoCoins") as! Int
}
}catch{
print("Failed")
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let detailController = segue.destination as! PopUpPurchaseViewController
detailController.ppromo = promoCODE
detailController.link = buyLink
detailController.coinToPurchase = Int(pointsToPurchase)!
}
//This is the unwind used by the transaction back button
#IBAction func unwindToItem(segue: UIStoryboardSegue) {
}
}
Here is the code in the transaction VC
import UIKit
import AMTabView
import CoreData
class MarketplaceViewController: UIViewController, TabItem {
#IBOutlet weak var sView: UIView!
#IBOutlet weak var evoCoinLabe: UILabel!
//For the sake of simplicity I only kept the Unwind functions
//MARK: - UNWIND FUNCTIONS
#IBAction func unwindToMainMarketView(segue: UIStoryboardSegue) {
}
}
How can I fix this error?
Please advise if my question was not clear or properly phrased (if so, sorry I am pretty new to all of this)
As #matt already said in his comment and the error clearly states, you cannot cast a MarketplaceViewController to a PopUpPurchaseViewController.
Furthermore instead of doing a forced cast, always look for a safe one like below. Doing so will prevent crashes.
if let detailController = segue.destination as? PopUpPurchaseViewController {
...
}
else {
// log failed to cast
}

Custom keyboard is crashing the app - Swift

I'm doing a test of a custom keyboard. This is what I need:
It has to have two UITextFields. Cannot be labels.
The keyboard is an embedded UIView.
The default keyboard should be disabled.
It cannot be a keyboard extension.
Not sure why the app is crashing. PS: Not all the keys are on the code yet. Here is an image of what I'm trying to do and the two View Controllers.
Edit: The error is: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
First ViewController:
import UIKit
class HomeVC: UIViewController, ButtonTapDelegate {
#IBOutlet var textField1: UITextField!
#IBOutlet var textField2: UITextField!
#IBOutlet var keyboardView: UIView!
var buttonPressed = [String]()
override func viewDidLoad() {
addKeyboard(view: keyboardView)
buttonPressed = [String]()
textField1.inputView = UIView()
textField2.inputView = UIView()
}
func addKeyboard(view: UIView) {
let keyboard = KeyboardVC(nibName: "KeyboardVC", bundle: nil)
view.addSubview(keyboard.view)
addChild(keyboard)
}
func didTapButton(sender: UIButton) {
if sender.tag == 5 {
textField1.text?.append(contentsOf: " ")
} else if sender.tag == 6 {
textField1.text?.removeAll()
buttonPressed = [String]()
} else {
let val = sender.titleLabel?.text
textField1.text?.append(contentsOf: val!)
}
self.textField1.text = buttonPressed.joined(separator: "")
}
}
Here is the second View Controller:
import UIKit
protocol ButtonTapDelegate {
func didTapButton(sender: UIButton)
}
class KeyboardVC: UIViewController {
var delegate: ButtonTapDelegate!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func buttons(_ sender: UIButton) {
delegate.didTapButton(sender: sender)
print(sender)
}
}
var delegate: ButtonTapDelegate!
An implicitly unwrapped optional is essentially a promise that you're definitely going to give the variable a value before you try to access it. The problem in this case is that you haven't done that. Most likely, you want to do this in your first view controller:
func addKeyboard(view: UIView) {
let keyboard = KeyboardVC(nibName: "KeyboardVC", bundle: nil)
keyboard.delegate = self // Now "delegate" will have a value before the function gets called
view.addSubview(keyboard.view)
addChild(keyboard)
}

How can I transfer UISlider value on SecondViewController to Alarm on FirstViewController?

I have two ViewControllers, FirstViewController and SecondViewController.
And there is UISlider on SecondViewController. There is an alarm on FirstViewController.
Now I want to transfer UISlider value, which is volume to alarm on FirstViewController.
ps. The function what I want to make is totally same as default iPhone setting slider.
I would be so happy so if you guys give me your knowledge, please.
import UIKit
import AVFoundation
class FirstViewController: UIViewController, AVAudioPlayerDelegate,
UITableViewDelegate, UITableViewDataSource{
let TODO = ["A", "B", "C"]
let notificationCenter = NotificationCenter.default
var volume = Float()
var counter = 0
var timer = Timer()
var startTime:Double = 0.0
var audioPlayer: AVAudioPlayer!
#IBOutlet weak var tableView: UITableView!
#IBAction func firstSwitch(_ sender: UISwitch)
{
if (sender).isOn
{
timer = Timer.scheduledTimer(withTimeInterval: 1 * 1, repeats: false, block: { timer in
self.audioPlayer.play()
self.audioPlayer.numberOfLoops = -1
print(self.audioPlayer.isPlaying)
})
}else{
timer.invalidate()
print("switch1stopped")
self.audioPlayer.stop()
}
}
notificationCenter.addObserver(self, selector: #selector(catchNotification(notification:)), name: NSNotification.Name(rawValue: "test"), object: nil)
}
#objc func catchNotification(notification: Notification) -> Void {
print("Catch notification")
audioPlayer.volume = volumeChane.value
//Use of unresolved identifier 'volumeChane'
}
///////////////////////////////////////////////////////////////////////////
import UIKit
import AVFoundation
class SecondViewController: UIViewController {
var audioPlayer: AVAudioPlayer!
let notificationCenter = NotificationCenter.default
#IBOutlet weak var volumeSlider: UISlider!
#IBOutlet weak var volumeLabel: UILabel!
#IBAction func volumeChange(_ sender: UISlider)
{
volumeLabel.text = String(Int(sender.value))
volumeSlider.value = sender.value
audioPlayer.volume = volumeSlider.value
notificationCenter.post(name: NSNotification.Name(rawValue: "test"), object: nil)
audioPlayer.play()
}
override func viewDidLoad()
{
super.viewDidLoad()
if let url=Bundle.main.url(forResource:"Alarm",withExtension:".mp3" )
{
do {
audioPlayer = try AVAudioPlayer(contentsOf:url)
audioPlayer?.play(atTime:1 * 10)
}catch{
audioPlayer = nil
}
}else{
fatalError("Url is nil")
}
}
extension Notification.Name
{
static let myNotificationName = Notification.Name("test")
}
Using NSNotificationCenter for a simple task such as this might be an overkill. You usually use closures to catch data changes in your components or view controllers.
In the SecondViewController create a variable containing a closure:
var onVolumeChange: ((value: Float) -> Void)?
Call it in the IBAction that monitors slider's onChange event.
#IBAction func volumeChange(_ sender: UISlider)
{
self.onVolumeChange?(sender.value)
}
Pass the onVolumeChange closure from the FirstViewController when navigating to the second one. I'm not sure how you perform navigation so I'll assume you do it programmatically.
let vc = UIStoryboard(name: "main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController")
vc.onVolumeChange = { value in
audioPlayer.volume = value
}
self.navigationController?.pushViewController(vc, animated: true)

Timer counts but doesn´t desplay

I just started to learn how to code and speak English^^
When I go from secondViewController to ViewController, a timer starts. A label shows the timer.
My problem is, when I go from secondViewController to ViewController for the second time, the label doesn´t show the timer. But the timer continue to count (I printed it out). Why the label doesn´t shoews the timer ?
I would be very grateful for your help
ViewController
var habit = 0
var statusFirst = false
class ViewController: UIViewController {
var firstTitel = ""
var secondTitels = ""
var timerTime = 0
var timer = Timer()
#IBOutlet weak var titelLabel: UILabel!
#IBOutlet weak var dateLabel: UILabel!
#IBOutlet weak var secondTitel: UILabel!
#IBOutlet weak var secondDate: UILabel!
#objc func processTimer() {
timerTime += 1
dateLabel.text = String(timerTime)
print(timerTime)
}
override func viewDidLoad() {
super.viewDidLoad()
// Hide Label - START
print(habit)
if habit == 0 {
titelLabel.isHidden = true
secondTitel.isHidden = true
dateLabel.isHidden = true
secondDate.isHidden = true
timer.invalidate()
}else if habit == 1 {
titelLabel.isHidden = false
secondTitel.isHidden = true
dateLabel.isHidden = false
secondDate.isHidden = true
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.processTimer), userInfo: nil, repeats: true)
}else if habit == 2 {
titelLabel.isHidden = false
secondTitel.isHidden = false
dateLabel.isHidden = false
secondDate.isHidden = false
}
// Hide Label - END
let titelObject = UserDefaults.standard.object(forKey: "firstTitel")
if let titel = titelObject as? String {
titelLabel.text = titel
}
let titellObject = UserDefaults.standard.object(forKey: "secondTitel")
if let titell = titellObject as? String {
secondTitel.text = titell
}
// 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.
}
}
SecondViewController
class SecondViewController: UIViewController {
var titelSecondViewController = ""
var dateSecondViewController = 0
#IBOutlet weak var titelField: UITextField!
#IBOutlet weak var dateField: UITextField!
#IBOutlet weak var okButton: UIButton!
#IBAction func okButtonAction(_ sender: Any) {
titelSecondViewController = titelField.text!
if let datefield = dateField.text {
if datefield == "" {
dateSecondViewController = 0
}else{
dateSecondViewController = Int(datefield)!
}
}else{
print("lol")
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
// Segue - Start
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toViewController" {
let viewController = segue.destination as! ViewController
habit += 1
print(habit)
if habit == 1 {
statusFirst = true
UserDefaults.standard.set(titelSecondViewController, forKey: "firstTitel")
}else if habit == 2{
UserDefaults.standard.set(titelSecondViewController, forKey: "secondTitel")
}else{
return
}
}
}
// Segue - End
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In first case habit = 1 so the timer is called
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.processTimer), userInfo: nil, repeats: true)
since the timer has a strong reference and you don't invalidate() it inside viewDidDisappear , it keeps the VC in memory after you dismiss it
//
In second time habit = 2 and you don't init the time inside it's if statement then the label of the second instance ( the presented one ) doesn't update , while the hidden dismissed one do