You can see from the photo the set up of my UI.
The objective is when the button is pressed if a number is greater than 9 the label on the first viewcontroller to change to "number is greater than 9" and if its smaller than 9 the segue should be triggered and the label on the secondView should change to "number is greater than 9..
This is what i have done so far, but when the segue is triggered the label on the secondView does not change..
class ViewController: UIViewController {
#IBOutlet weak var labelFirst: UILabel!
#IBOutlet weak var numberEntered: UITextField!
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.
}
override func shouldPerformSegueWithIdentifier(identifier: String!, sender: AnyObject!) -> Bool {
var number: Int? {
get{
return Int(numberEntered.text!)
}
}
if number>9 {
labelFirst.text="number is greater than 9"
return false}
else {
return true
func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier=="segue"){
let destinationVC:secondView = segue.destinationViewController as! secondView
destinationVC.outputText="number is smaller than 9"
}
}
}
}
}
the segue is connected to the button and directs to the second view.
secondView:
import UIKit
class secondView: UIViewController {
#IBOutlet weak var label: UILabel!
var outputText=String()
override func viewDidLoad() {
label.text=outputText
}
}
ui
Your prepareForSegue method is in the wrong place , it should be outside the shouldPerfomSegue method and marked with override.
The reason it is not updating on the second screen is because you are doing it inside viewDidLoad. That only happens once. Move the code to viewWillAppear.
import UIKit
class secondView: UIViewController {
#IBOutlet weak var label: UILabel!
var outputText=String()
override func viewWillAppear() {
super.viewWillAppear()
label.text = outputText
}
}
Related
I have this code:
MainViewControler:
class MainViewControler: UIViewController, ContainerToMaster {
#IBOutlet weak var systemContainerView: UIView!
#IBOutlet weak var favoriteProductBtn2: UIButton!
weak var containerViewController: Calculator1ViewController?
func changeBtn() {
favoriteProductBtn2.isHidden = true
print("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
}
}
CallculatorViewController:
#IBOutlet weak var containerView: UIView!
class CallculatorViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
Calculator1ViewController:
protocol ContainerToMaster {
func changeBtn()
}
class Calculator1ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
containerToMaster?.changeBtn()
}
}
I have such an application layout:
Main view = MainViewControler.
In MainViewControler, I have a containerView (systemContainerView) in which the MainViewControler is located
In the CallculatorViewController, I have the next containerView in which the Calculator1ViewController is located.
When entering the Calculator1ViewController the function: containerToMaster?.changeBtn() should start (it should work in MainViewControler).
The problem is - this function does not work :(
Does anyone know how to fix it?
A contained viewController is embedded with an embed segue. You need to override prepare(for:sender) and set self as the containerToMaster delegate in the destination viewController. Your situation is complicated by the fact that you have a container view embedded in another container view, so you'll need to set up two delegates and pass the button call back:
protocol ContainerToMaster {
func changeBtn()
}
class MainViewControler: UIViewController, ContainerToMaster {
#IBOutlet weak var systemContainerView: UIView!
#IBOutlet weak var favoriteProductBtn2: UIButton!
weak var containerViewController: Calculator1ViewController?
func changeBtn() {
favoriteProductBtn2.isHidden = true
print("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destVC = segue.destination as? CallculatorViewController {
destVC.containerToMaster = self
}
}
}
class CallculatorViewController: UIViewController, ContainerToMaster {
weak var containerToMaster: ContainerToMaster?
override func viewDidLoad() {
super.viewDidLoad()
}
func changeBtn() {
// pass the button call back
containerToMaster?.changeBtn()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destVC = segue.destination as? Calculator1ViewController {
destVC.containerToMaster = self
}
}
}
class Calculator1ViewController: UIViewController {
weak var containerToMaster: ContainerToMaster?
override func viewDidLoad() {
super.viewDidLoad()
containerToMaster?.changeBtn()
}
}
Right now on my Storyboard I have a View that I have a segue connecting to a scroll view. I want to make it so that the stuff (an image, label, buttons) on the first View on the Storyboard will go to the Scrollview once the segue button is pressed.
Is there a way that when I segue into the Scroll View the Scroll View will only be the size that it needs to be to fit the newly inputted information from the first View.
Also is there a way that I can save what was put into the Scroll View so the users can add to the scroll view to make it larger. I have Firebase in my app if I need to use that to save the Scroll View information.
Below are my two view controllers (I have no view controller for my scroll view but I can make one if I need it) and a screenshot of my storyboard if that will help!
import UIKit
class PhotoShareViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var contentTextView: UITextView!
#IBOutlet weak var thatTextField: UITextField!
#IBOutlet weak var thisTextField: UITextField!
var presenter: PhotoShareModuleInterface!
var image: UIImage!
#IBAction func thisUploadPhoto(_ sender: Any) {
if thisTextField.text != "" && thatTextField.text != "" {
performSegue(withIdentifier: "segue", sender: nil)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let photoShareLabelViewController = segue.destination as! PhotoShareLabelViewController
photoShareLabelViewController.thisString = thisTextField.text!
photoShareLabelViewController.thatString = thatTextField.text!
photoShareLabelViewController.imageLoaded = image
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
imageView.image = image
}
override var prefersStatusBarHidden: Bool {
return true
}
#IBAction func didTapCancel(_ sender: AnyObject) {
presenter.cancel()
presenter.pop()
}
#IBAction func didTapDone(_ sender: AnyObject) {
guard let message = thatTextField.text, !message.isEmpty else {
return
}
guard let messageOne = thisTextField.text, !messageOne.isEmpty else {
return
}
presenter.finish(with: image, content:message)
presenter.dismiss()
}
}
extension PhotoShareViewController: PhotoShareViewInterface {
var controller: UIViewController? {
return self
}
}
import UIKit
class PhotoShareLabelViewController: UIViewController {
#IBOutlet weak var thisLabel: UILabel!
#IBOutlet weak var thatLabel: UILabel!
#IBOutlet weak var thisButton: UIButton!
#IBOutlet weak var thatButton: UIButton!
#IBOutlet weak var changedImage: UIImageView!
var thisCounter = 0
var thatCounter = 0
#IBAction func pressedDoneButtonLabel(_ sender: Any) {
print("done")
}
var presenter: PhotoShareModuleInterface!
var imageLoaded: UIImage!
#IBAction func pressedThisButton(_ sender: Any) {
thisCounter += 1
print(thisCounter)
}
#IBAction func pressedThatButton(_ sender: Any) {
thatCounter += 1
print(thatCounter)
}
var thisString = String()
var thatString = String()
#IBAction func pressedButtonDone(_ sender: Any) {
print("done")
}
// #IBAction func pressedButtonCancel(_ sender: Any) {
// print("cancel")
// }
override func viewDidLoad() {
super.viewDidLoad()
thisLabel.text = thisString
thisButton.setTitle(thisString, for: UIControlState.normal)
thatLabel.text = thatString
thatButton.setTitle(thatString, for: UIControlState.normal)
changedImage.image = imageLoaded
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Thanks so much! Any and all help is appreciated!
It sounds like what you're trying to do was practically made for a UITableView or UICollectionView. UITableView is actually a subclass of UIScrollView for good reason – the content keeps expanding as needed. You will need to change your data model to be an array of whatever it is you want to display, but that should be fairly easy.
I'm not entirely sure what you're trying to achieve but if I'm correct you have a dynamically changing amount of photos?
If that's the case I would suggest you look at CollectionViews. This will handle the scroll view size for you and help formatting.
Consider these two links
https://developer.apple.com/documentation/uikit/uicollectionview
Great tutorial:
https://www.raywenderlich.com/136159/uicollectionview-tutorial-getting-started
I am trying to print out the text of a UITextField to the console when a button is tapped. However, I am getting an error that says it cannot unwrap a nil. By default, I have a value typed into in and when I insert a new value, both produce this error. These IBOutlets are appropriately linked.
#IBOutlet weak var entranceFeeTextField: UITextField!
#IBAction func saveButtonTapped(sender: UIButton) {
print("The entrance fee is \(entranceFeeTextField.text)")
}
My class is only conforming to UITableViewCell and UITextFieldDelegate, and not to UIViewController. Could that be the error?
Do something like this
if let text = self.entranceFeeTextField.text {
print(text)
}
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var theTextField: UITextField!
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 onButtonPressed(sender: UIButton) {
print(self.theTextField.text)
}
}
http://i.stack.imgur.com/NXYaK.png
It Should Be Like
#IBOutlet weak var test: UITextField!
#IBAction func btn(sender: AnyObject) {
let txt = test.text!
print(txt)
}
Hope It Helps.
It shows that the source view controler does not have the string variable so what should I do?
This is the code in my source view controller
#IBOutlet var textfield: UITextField!
#IBOutlet var tofirstbutton: UIButton!
#IBOutlet var tosecondbutton: UIButton!
var s:String!
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "unwindtosecond"{
self.s=self.textfield.text
}
}
and this is the code in my destination view controller
#IBOutlet var textfield: UITextField!
#IBOutlet var tofirstbutton: UIButton!
#IBOutlet var tothirdbutton: UIButton!
#IBOutlet var label: UILabel!
#IBAction func unwindtosecond(Segue:UIStoryboardSegue){
if Segue.identifier == "unwindtosecond" {
var source:ViewController = Segue.sourceViewController as ViewController
var s:String = source.s!
}
I am getting an error saying that viewcontroller does not have a member named s.
Here is some example code to implement a main controller segueing to a second VC, and the second unwinding to the main controller. Notice that in the function the second cVC unwinds to, you can refer to the second controller and access a variable in the second controller. If you want to initialize a variable in the second VC from the main VC, you can use a prepareForSegue in the main VC.
import UIKit
class ViewController: UIViewController {
var varInMainVC = ""
#IBAction func segueToSecondVCAction(sender: UIButton) {
performSegueWithIdentifier("segueToSecondVC", sender: self)
}
#IBAction func unwindFromSecondVC(segue: UIStoryboardSegue) {
// return here from second VC
let vc = segue.sourceViewController as! SecondViewController
varInMainVC = vc.varInSecondVC
println("varInMainVC = \(varInMainVC)")
}
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.
}
}
import UIKit
class SecondViewController: UIViewController {
var varInSecondVC = ""
var varLoadedFromMainVC = 0
override func viewDidLoad() {
super.viewDidLoad()
varInSecondVC = "Test String to be returned"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Try these solutions:
Protocol delegate: https://stackoverflow.com/a/24299231/1925852
Setup a closure as a property: https://stackoverflow.com/a/24318588/1925852
Why can't I pass data from one view controller class to another view controller class when they are in the same .swift file?
I've done both of the tutorials linked bellow in an effort to understand passing data, and both have you make another .swift file for you second view controller. When I followed them exactly it works. When I do everything the same but just put the class SecondViewController in the same .swift file as the class FirstViewController it doesn't work. Why?
I'm building an application with three view controllers and I'd rather just keep all the code in one file if I can. Is this why it's not working or is it just bad form?
Tutorials:
How to Pass Data from View Controller (Swift : Xcode) on YouTube
Segue Between Swift View Controllers on CodingExplorer
This works:
// ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet var TextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var DestViewController: ViewTwo = segue.destinationViewController as ViewTwo
DestViewController.LabelText = TextField.text
}
}
// ViewTwo.swift
import UIKit
class ViewTwo: UIViewController {
#IBOutlet var Label: UILabel!
var LabelText = String()
override func viewDidLoad() {
Label.text = LabelText
}
}
This does not:
// ViewController.swift
import UIKit
class ViewController: UIViewController {
#IBOutlet var TextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var DestViewController: ViewTwo = segue.destinationViewController as ViewTwo
DestViewController.LabelText = TextField.text
}
}
class ViewTwo: UIViewController {
#IBOutlet var Label: UILabel!
var LabelText = String()
override func viewDidLoad() {
Label.text = LabelText
}
}
Working fine for me.
Have you set the classes for your views properly? The view with your textField (and probably a button to ViewTwo) should be set to ViewController and your second view with the label should be set to ViewTwo.
Check the connections between your label/textField. Are they properly connected to your class?
This is the code I used, which should be exactly the same:
import UIKit
class ViewController: UIViewController {
#IBOutlet var TextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var DestViewController = segue.destinationViewController as! ViewTwo
DestViewController.LabelText = TextField.text
}
}
class ViewTwo: UIViewController {
#IBOutlet var Label: UILabel!
var LabelText = String()
override func viewDidLoad() {
Label.text = LabelText
}
}