I am new to iOS programming and I am trying to build a simple calculator app, but I am stuck at connecting actions between two viewControllers. I am trying to change the value of a segmentControl of the firstView by manipulating the same control in my second view. Any suggestions how to do it? Thank you. Below are the code and screenshots of it.
code first viewController
class ViewController: UIViewController {
#IBOutlet weak var billField: UITextField!
#IBOutlet weak var totalLabel: UILabel!
#IBOutlet weak var tipLabel: UILabel!
#IBOutlet weak var tipControll: UISegmentedControl!
#IBAction func onTap(_ sender: Any) {
//dismiss the keyboard when we tap anywhere from the screen
view.endEditing(true)
}
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.
}
#IBAction func calculateTip(_ sender: AnyObject) {
//calculate
let percentage = [0.18, 0.2, 0.25]
let bill = Double(billField.text!) ?? 0
let tip = bill * percentage[tipControll.selectedSegmentIndex]
let total = bill + tip
//set the labels
tipLabel.text = String(format: "$%.2f", tip)
totalLabel.text = String(format: "$%.2f", total)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("view will appear")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("view did appear")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("View will disappear")
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
print("view did disappeared")
}
code second viewController
import UIKit
class SettingViewController: UIViewController {
#IBOutlet weak var segmentControlLabel: UISegmentedControl!
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 prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
#IBAction func onTipChanged(_ sender: Any) {
}
}
Screen
I think you should use UserDefaults to connect data because it will save your tip default for next time open app.
In second viewcontroller
override func viewDidLoad() {
super.viewDidLoad()
// Get value saved in last time here.
//NSUserDefaults.standardUserDefaults().integerForKey("DefaultTip")
}
#IBAction func onTipChanged(_ sender: Any) {
// Set value when tip changed
//NSUserDefaults.standardUserDefaults().setInteger(value, forKey: "DefaultTip")
}
In first viewcontroller
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("view will appear")
// Get value saved in last time here.
//NSUserDefaults.standardUserDefaults().integerForKey("DefaultTip")
}
And remember register default value
NSUserDefaults.standardUserDefaults().registerDefaults([
"DefaultTip": <your default value>
])
at AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
NSUserDefaults.standardUserDefaults().registerDefaults([
"DefaultTip": <your default value>
])
return true
}
Related
I have two view controllers A,B in controller scenes. I can create a segue from A -> B.
I also create an unwind segue from B -> A with a prepare function.
This function is being executed but the value is not being passed to passedDataString is not being passed back.
import UIKit
class homeViewController: UIViewController , UIAlertViewDelegate {
#IBOutlet weak var returnStatusLbl: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
var passedDataString = "QR Return not set"
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
returnStatusLbl.text = passedDataString
}
#IBAction func QRtoHome( _ sender: UIStoryboardSegue) {}
}
import UIKit
class QRViewController: UIViewController {
#IBOutlet weak var wherefromLbl: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destVC = segue.destination as! homeViewController
destVC.passedDataString = "From Done"
}
}
When you return by unwind, viewWillAppear is not called.
You could use an observer:
var passedDataString : String = "QR Return not set" {
didSet {
returnStatusLbl.text = passedDataString
}
}
I found this works:
#IBAction func QRtoHome( _ sender: UIStoryboardSegue) {
returnStatusLbl.text = passedDataString
}
I want to have the pretty simple transition from the home view where the user enters the text in the textfield, then have its segue go to the next view controller. I did implement the function textFieldShouldReturn(textField: UITextField) -> Bool which tries to perform the segue, but didn't get the desired result.
Here's the part of the code
class LogInVC: UIViewController {
#IBOutlet weak var logInLabel: UILabel!
#IBOutlet weak var logInField: UITextField!
override func viewDidLoad() {
NSLog("LogIn view loaded, setting delegate")
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(_ animated: Bool) {
NSLog("viewWillAppear: Performing possible queued updates")
textFieldShouldReturn(textField: logInField)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let autoCheckInVC = segue.destination as?
AutocheckInVC else {
preconditionFailure("Wrong destination type: \(segue.destination)")
}
guard logInField.text != nil else {
preconditionFailure("Text property should not be nil")
}
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
self.performSegue(withIdentifier: "AutoCheckInVC", sender: self)
return true
}
}
Any quick help for debugging this would be so greatly appreciated. I have tried quite much time fixing this, but I haven't found the way out!!!
You have a few errors in your code:
To be able to call textFieldShouldReturn you need to inherit from UITextFieldDelegate and set the delegate of your textField, logInField.delegate = self
Don´t call textFieldShouldReturn from viewDidAppear
Use the latest syntax for the method textFieldShouldReturn
You got the warning result of call to this method is unused because it was never called since you never had the delegates
Try this code instead of yours:
class LogInVC: UIViewController, UITextFieldDelegate {
#IBOutlet weak var logInLabel: UILabel!
#IBOutlet weak var logInField: UITextField!
override func viewDidLoad() {
NSLog("LogIn view loaded, setting delegate")
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
logInField.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
NSLog("viewWillAppear: Performing possible queued updates")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let autoCheckInVC = segue.destination as?
ViewController else {
preconditionFailure("Wrong destination type: \(segue.destination)")
}
guard logInField.text != nil else {
preconditionFailure("Text property should not be nil")
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.performSegue(withIdentifier: "AutoCheckInVC", sender: self)
return true
}
}
How do i set up a label so that when a button is pressed then it will change that value displayed on the label and set it up that each time a button is pressed it they will all just add to the previous number that was pressed - and is it possible to set up 2 view scenes on the same view controller?
#IBOutlet weak var creditLabel: UILabel!
var savedNum:Int = "Credits: /0"
var Money : Int!
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.
}
#IBAction func oneDollar(_ sender: Any) {
let oneDollar = 1
}
#IBAction func fiveDollars(_ sender: Any) {
let fiveDollars = 5
}
#IBAction func tenDollars(_ sender: Any) {
let tenDollars = 10
}
#IBAction func twentyDollars(_ sender: Any) {
let twentyDollars = 20
}
#IBAction func fiftyDollars(_ sender: Any) {
let fiftyDollars = 50
}
#IBAction func oneHundredDollars(_ sender: Any) {
let oneHundredDollars = 110
}
}
I think what you're trying to do is something like this…
class ViewController: UIViewController {
#IBOutlet weak var creditLabel: UILabel!
var credit = 0 {
didSet {
creditLabel.text = "Credit: $\(credit)"
}
}
override func viewDidLoad() {
super.viewDidLoad()
credit = 0
}
#IBAction func oneDollar(_ sender: Any) {
credit += 1
}
#IBAction func fiveDollars(_ sender: Any) {
credit += 5
}
// etc
}
Is your Label connected to your UIViewController? What about the corresponding actions? Are you connecting the same actions to the same button? Need more information to help solve your error that's being thrown.
I have the following:
class Settings: UIViewController {
#IBAction func CitySend(sender: AnyObject) {
self.performSegue(withIdentifier: "senddata", sender: self)
}
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "senddata" {
let Mainview = segue.destination as! ViewController
Mainview.label = textField.text!
}
}
}
My mainview looks like this:
class ViewController: UIViewController {
#IBOutlet var city: UILabel!
var label: String = ""
override func viewDidLoad() {
super.viewDidLoad()
city.text = label
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
im not sure, if this is how i should even do this, but to me the logic is that i only want to allow this segue to pass a string to my label in my mainview if the button is pressed (Like a save button)
However as to what i have made now, nothing happens, and it gives me the 1: signal SIGABRT error, whenever i press the button.
Use the following code:
ViewController.swift
import UIKit
class ViewController: UIViewController, SecondViewControllerProtocol{
#IBOutlet weak var dataLabel: UILabel!
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.
}
#IBAction func navigateToSecondViewControllerOnButtonClick(_ sender: AnyObject) {
let secondVC: ViewController2 = storyboard?.instantiateViewController(withIdentifier: "viewcont2") as! ViewController2
secondVC.delegate = self
self.navigationController?.pushViewController(secondVC, animated: true)
}
func saveData(data: String){
dataLabel.text = data
}
}
ViewController2.swift
import UIKit
protocol SecondViewControllerProtocol {
func saveData(data: String) // this function the first controllers
}
class ViewController2: UIViewController {
var delegate: SecondViewControllerProtocol?
#IBOutlet weak var dataTextField: UITextField!
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 saveButtonClicked(_ sender: AnyObject) {
delegate?.saveData(data: dataTextField.text!)
}
}
Storyboard screenshot:
Please check my GitHub link below to test sample:
https://github.com/k-sathireddy/PassingDataThroughSegue
#IBAction func CitySend(sender: AnyObject) {
self.performSegue(withIdentifier: "senddata", sender: textField.text)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch (segue.identifier, segue.destination, sender) {
case (.Some("senddata"), let controller as ViewController, let text as String):
controller.label = text
default:
break
}
}
I want to segue into a UITableView Search. I already have the uitableview and search bar implemented and working. Now I want to add a button, that when clicked, opens up the search view with the keyboard out. How can I implement this?
Challenge: How can I put this button on separate view controller?
I have looked up ways to segue into a search bar, but all I have found are ways to segue out of a search.
My Code:
/*Search*/
var searched: Bool = false
#IBOutlet weak var searchBarReal: UISearchBar!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
getSortedSectionList()
tableView.reloadData()
if searched {
searchBarReal.becomeFirstResponder()
searched = false
}
}
override func viewDidLoad() {
super.viewDidLoad()
let nav = self.navigationController?.navigationBar
nav?.backgroundColor = UIColor.whiteColor()
nav?.tintColor = UIColor.whiteColor()
setUpIcons()
searchBarReal.delegate = self
}
You can tell your searchBar to becomeFirstResponder.
code example:
Initial View Controller
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.
}
#IBAction func bttnTouched(sender: AnyObject) {
performSegueWithIdentifier("next", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "next" {
let nextVc = segue.destinationViewController as! NextViewController
nextVc.shouldSearchBarRespond = true
}
}
}
Next View Controller
import UIKit
class NextViewController: UIViewController, UISearchBarDelegate {
#IBOutlet weak var searchBar: UISearchBar!
var shouldSearchBarRespond: Bool?
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillAppear(animated: Bool) {
if shouldSearchBarRespond == true {
searchBar.becomeFirstResponder()
}
}
}