PrepareForSegue Swift (changing UIImage and UILabel) - xcode

So I'm writing the prepareForSegue for my app but having issue setting up the code for changing the UIImage and UILabel for the destination ViewController.
What would be the code to change the images and UILabel when segue to the next ViewController?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "toTest") {
let destViewController : data3ViewController = segue.destinationViewController as data3ViewController
}
}

I you have in your data3ViewController an UILabel and an UIImage , let says named
myLabel and myImage respectively , then you should do the following :
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "toTest") {
var destViewController : data3ViewController = segue.destinationViewController as data3ViewController
let _ = destViewController.view
destViewController.myLabel.text = "Something"
destViewController.myImage = UIImage(named: "photo")
}
}
The call above to destViewController.view ensure that the #IBOutlet's are initialized before set it values.
I hope this help you

Related

Pass data through segue to SWRevealController

I'm making an app and it has a simple login page that for now will just a send a String (username) to the next screen. The next screen however uses an SWRevealViewController (https://github.com/John-Lluch/SWRevealViewController).
I've tried
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let vc = segue.destinationViewController as! MenuController
vc.userType = userID.text
}
But that gives me the error Could not cast value of type 'SWRevealViewController' to 'MenuController'. MenuController is the class I am trying to pass the data to.
I know this isn't a common Controller but hopefully somebody can help.
Try this instead.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let revealVC = segue.destinationViewController as? SWRevealViewController {
if let menuVC = revealVC.revealViewController as? MenuController {
menuVC.userType = userID.text
}
}
}

call the standard segue by tapping a button

i've a UITableView with two Columns: a text colomn and an image
for the textColumn on the left, i use a standarard segue, everytehing is fine...
Now i want to implement the same action, when the right button is tapped
i tried it with a new segue imageDisplay for the right (image) column
let tapRecognizerImage = UITapGestureRecognizer(target: self, action: Selector("imageAction:"))
cell.imageButton.addGestureRecognizer(tapRecognizerImage)
}
func imageAction(sender: UITapGestureRecognizer) {
performSegueWithIdentifier("imageDisplay", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
let indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow!
let controller = segue.destinationViewController as! DetailViewController
controller.kategorie = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Kategorien
} else if segue.identifier == "imageDisplay" {
let indexPath : NSIndexPath = self.tableView.indexPathForSelectedRow!
let controller = segue.destinationViewController as! DetailViewController
controller.kategorie = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Kategorien
}
}
Now in
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
i get the error
fatal error: unexpectedly found nil while unwrapping an Optional value
This is, cause self.tableView.indexPathForSelectedRow! is nil!
Perhaps, thereĀ“s a much simpier way ro resolve this???
Its nil because you do not select a row by taping on an image.
Try to set cell.imageButton.tag to indexPath.row (in cellForRowAtIndexPath) and use sender.tag instead of indexPath in prepareForSegue.
If you really need an NSIndexPath in prepareForSegue just create one and set its row to sender.tag

Access container view child properties swift

What I want to achieve:
User presses the button in the ViewController then, the color of the button placed in the container view should change its color to red.
How can I get access of the button placed in the container view, from the ViewController?
Step by step:
Name the segue between your view controller and container view controller.
Add a property to your view controller which will contain the container view controller.
In your view controller implement a method prepareForSegue(_:sender:).
In the method check if segue.identifier equals the identifier you specified in step 1.
If true, then save the segue.destinationViewController to your property from step 2.
Now you have the container view controller stored in your property so you can do customization from your class. You should have the view controller stored in viewDidLoad() method already.
Example:
var containerViewController: YourContainerViewControllerClass?
let containerSegueName = "testSegue"
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == containerSegueName {
containerViewController = segue.destinationViewController as? YourContainerViewControllerClass
}
}
I recommend not to rely on segue.identifier, but rather test for destination type directly:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if let vc = segue.destination as? YourViewController {
vc.someVariable = true
}
}
This way you avoid mistakes with a misspelled segue name.
Swift 4, Xcode 9.4.1
var contentViewController : UIContentViewController?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == containerSegueName {
contentViewController = segue.destination as? UIContentViewController
}
}
Swift 3 for macOS:
// MARK: - Container View Controller
var containerViewController: ContainerViewController?
let containerSegueIdentifier = "Container Segue"
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if segue.identifier == containerSegueIdentifier {
if let connectContainerViewController = segue.destinationController as? FormationViewController {
formationViewController = connectContainerViewController
}
}
}
Check identifier and controller class.

UiTextField not changing after Prepare for Segue

I am having a strange little problem when I segue to the next ViewController. I have it set up so that when I segue it should change the TextField of the next ViewController but for some reason or another it isn't. The segue works but the TextField doesn't change.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Edit" {
let cell = sender as! UITableViewCell
let indexPath = TaskTableViews.indexPathForCell(cell)
let itemController: TaskManager = segue.destinationViewController as! TaskManager
let nItem: List = frc.objectAtIndexPath(indexPath!) as! List
itemController.nItem = nItem
}
if (segue.identifier == "Give") {
let itemController : TaskManager = segue.destinationViewController as! TaskManager
itemController.addTaskText = "Great"
}
}
Heres the ViewDidLoad of my secondViewController..
// View Did Load
override func viewDidLoad() {
super.viewDidLoad()
if nItem != nil {
addTask.text = (nItem?.taskName)!
}
addTask.placeholder = "Title ..."
addTaskText = addTask.text!
Check that you're actually performing the segue with the relevant identifier and take a look at prepareForSegue. If it is like the code below it should work. Also, in your second ViewController you can set the text in your textField in viewDidLoad. Just make sure that the data is actually being passed from the first to the second ViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "Great" {
let itemController = segue.destinationViewController as! YourDestinationViewController
itemController.someStringVariable = "Great"
}
}
In your second ViewController you can declare a variable that will get it's value during the segue and then use that variable's value to set the text of your textField, like this:
var someStringVariable: String!
override func viewDidLoad() {
super.viewDidLoad()
//Check if the value has been set to your string and if it has set it to be the textField's text
if someStringVariable != nil {
textField.text = someStringVariable
}
}

Swift: prepareForSegue with two different segues

I have 2 UIButtons on a view.
Each of them are linked to 2 different views.
They have to pass different data depending which button you just tapped.
I know there is different way to segue but I want to use the prepareForSegue version for each (seems more clear for me to have the segue drawn on the storyboard and some code to explain what happened).
I tried this...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue != "historySegue") {
let controller = segue.destinationViewController as! ResultViewController
controller.match = self.match
} else {
let controller = segue.destinationViewController as! HistoryViewController
controller.history = self.history
}
}
#IBAction func showHistory(sender: UIButton) {
performSegueWithIdentifier("historySegue", sender: self)
}
#IBAction func match(sender: UIButton) {
performSegueWithIdentifier("matchSegue", sender: self)
}
But I got an error when I click the buttons
(lldb)
Take out your IBActions (making sure to delete them in the Connections Inspector via the right side bar in the Interface Builder as well as in your code). For the segues, just use the Interface Builder, make sure both segue's identifiers are correct, then try this prepareForSegue method:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "matchSegue" {
let controller = segue.destinationViewController as! ResultViewController
controller.match = self.match
} else if segue.identifier == "historySegue" {
let controller = segue.destinationViewController as! HistoryViewController
controller.history = self.history
}
}
You could switch it...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let identifier = segue.identifier {
switch identifier {
case "matchSegue":
let controller = segue.destinationViewController as! ResultViewController
controller.match = self.match
case "historySegue":
let controller = segue.destinationViewController as! HistoryViewController
controller.history = self.history
}
}
}
You should compare the segue.identifier with the string not segue:
segue.identifier == "historySegue"
It won't fix your problem but it helps later.
I believe you have added an breakpoint and your app just stop at it. Remove the breakepoint and it will work.
prepareForSegue with two different segues
when you click on button uialert controller will show it will give you three options 1. physical, 2. online and 3. cancel.
#objc func twoSegues(sender : UIButton) {
let alert = UIAlertController(title: "Update Request", message: "Are you sure to update the record!", preferredStyle: .alert)
let yes = UIAlertAction(title: "Yes", style: .default, handler: { [weak self] (UIAlertAction) in
if(serviceType == "physical") {
DispatchQueue.main.async {
self?.performSegue(withIdentifier: "physical", sender: self?.myArray[id!].serviceID)
}
}
if(serviceType == "online") {
DispatchQueue.main.async {
self?.performSegue(withIdentifier: "online", sender: self?.myArray[id!].serviceID)
}
}
})
let no = UIAlertAction(title: "No", style: .default, handler: nil)
alert.addAction(yes)
alert.addAction(no)
self.present(alert, animated: true, completion: nil)
}
}
In order to navigate different segues in objective C you need to follow these actions.
Click on the actual segue on storyboard
Go to attribute inspector and rename the identifier of the segue
customize the code as following, here's an example:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"segueNumberOne"]){
YourViewController *functionalityViewController = [segue destinationViewController];
functionalityViewController.someProperty = someValue;
NSLog(#"move to segue number 1");
}else if ([segue.identifier isEqualToString:#"segueNumberTwo"]){
NSLog(#"move to segue number 2");
}

Resources