Attempting to segue from Objective-C to Swift VC
After discussion in Chat and fixing various issues, I'll take them one by one:
> *** Assertion failure in -[UIApplication _cachedSystemAnimationFenceCreatingIfNecessary:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3698.21.8/UIApplication.m:1707
> *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'accessing _cachedSystemAnimationFence requires the main thread'
That's the first issue causing a crash. This is talking about an internal method of CocoaTouch needed to be called in main thread.
The issue lies on your performSegueWithIdentifier:sender:
. All UI related calls have to be done in main thread.
To fix it:
dispatch_async(dispatch_get_main_queue(), ^(){
[self performSegueWithIdentifier:@"brandSegue" sender:self];
});
Fixing this revealed a second issue:
it segues but it trigger twice, do you know why this may happen?
You are doing this:
for (size_t i = 0; i < trackableCount; i++)
{
if (somethingTest)
{
[self performSegueWithIdentifier:@"brandSegue" sender:self];
}
}
Who said that in your for loop you don't valid multiple times somethingTest
?
To fix it (I'm talking about the logic, I didn't do the dispatch_async(dispatch_get_main_queue(){()}
part to avoid adding noise to the algorithm).
//Declare a var before the for loop
BOOL seguedNeedsToBeDone = FALSE;
for (size_t i = 0; i < trackableCount; i++)
{
if (somethingTest)
{
seguedNeedsToBeDone = TRUE;
}
}
//Perform the segue after the for loop if needed
if (seguedNeedsToBeDone)
{
[self performSegueWithIdentifier:@"brandSegue" sender:self];
}
Next issue, passing data to the Destination ViewController:
JSONViewController *destViewController = segue.destinationViewController;
destViewController.brand = @"something";
You are mixing Swift & Objective-C, since XCode was complaining about not knowing brand
being a property of JSONViewController
object, you needed to add @objc
before the declaration of the var. More detailed answer can be found here.
Finally, a tip to pass the data of you for loop is using the sender (it's faster in term of coding than creating another var, etc.):
//Calling the performSegue with custom value to pass
[self performSegueWithIdentifier:@"brandSegue" sender:someVarToSend];
//Passing the custom value
destViewController.brand = someVarToSend;
Segue from Obj-c to swift can't find property
If you are using Swift file in objc classes Bridging header won't help here.
Xcode will create Header file which you need to import
First goto build settings and search for Defines Modules and set it to true.
Now in .m
file add following header file
#import "YourTargetName-Swift.h"
and build the project
and also add @objc
before your property
Hope it is helpful
Performsegue from another viewcontroller doesnt' work
In your buttonTapped()
function, you are creating a new instance of "dashboardViewController", and then trying to perform a segue... but you haven't added that new VC or its view to the hierarchy, so even if the segue were to be performed, there's nothing to see.
What you want to do is use the protocol / delegate pattern.
Create a protocol so your button tap inside "sideViewController" can tell its delegate (the "main" view controller) to tell the existing instance of "dashboardViewController" to perform the segue.
Protocols and delegates function the same in Swift as in Obj-C ... just different syntax.
Prepare for segue function can't pass data to another VC Swift,
First of all rather than declaring an extra property or saving the value to UserDefaults
you can pass the string in the sender
parameter
let action = UIAlertAction(title: "Download", style: .default) { (action) in
guard let textField = alert.textFields?.first else {return}
self.performSegue(withIdentifier: "segAdd", sender: textField.text!)
}
Your way to determine the destination view controller is wrong. Ask the segue
for the destination
. And you can force downcast the type. The code must not crash if the segue is designed correctly.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segAdd" {
let destinationVC = segue.destination as! BrowserWebViewController
destinationVC.urlFromDownloads = sender as! String
print("The value of destinationVC?.urlFromDownloads is \(destinationVC.urlFromDownloads)")
}
}
Push Segue triggers a Modal Segue that leads to VC with no navigation bar
To fix this you need to connect the modal segue from VC A to VC B’s Navigation Controller.
How to properly segue between view controllers
Have you tried removing the manual IBAction code for the button and just using the segue made on the Storyboard? It may be trying to segue twice simultaneously if you both used the Storyboard and the Class file to do it.
Edit: All the code in my working example for the two view controllers
First View Controller:
class OneViewController: UIViewController {
@IBOutlet var label1: UILabel
@IBOutlet var label2: UILabel
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
Second View Controller:
class TwoViewController: UIViewController {
@IBOutlet var upperlabel: UILabel
@IBOutlet var lowerlabel: UILabel
@IBOutlet var textbox: UITextField
@IBAction func button(sender: AnyObject) {
var percent = textbox.text
lowerlabel.text = percent
}
override func viewDidLoad() {
super.viewDidLoad()
}
Can't add an image due to NDA, but Storyboard is just NavigationController>VC1>VC2, with two labels in each VC, a text box in VC2, and a button in each. Only the second button has an action in its VC class.
Setting a property in a segue with Navigation Controller containing another view
Since the destination view controller is actually the navigation controller, try accessing the root view like so:
UINavigationController *navController = [segue destinationViewController];
ShowItemsTableViewController *SITViewController = (ShowItemsTableViewController *)([navController viewControllers][0]);
[SITViewController setItems:[self itemsFromCoreData]];
Unable to segue from Spritekit SKScene to another UIViewController, XCODE8/Swift
Just for anyone who might come across this, I solved it by using notification center. Ie added a notification observer on the parent view controller of the game scenes (which calls a function that performs the segue), and at the end point in the game where I wanted to do the segue, I posted to that notification, and it works great.
adding observer in ViewDidLoad of UIViewController:
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(GameViewController.doaSegue), name: NSNotification.Name(rawValue: "doaSegue"), object: nil)
}
func doaSegue(){
performSegue(withIdentifier: "toNext", sender: self)
self.view.removeFromSuperview()
self.view = nil
}
And then calling it from within the game SKScene:
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "doaSegue"), object: nil)
Related Topics
Swift Computed Properties Cannot Be Used in Init
Video with Gpuimagechromakeyfilter Has Tint When Played in Transparent Gpuimageview
What Is a Safe Way to Turn Streamed (Utf8) Data into a String
Coredata Conditionally Fetching on Nsdate Using Nspredicate (Swift)
How to Reuse Struct on Swift? or Is There Any Other Way
How to Set Response Data into Todayextenstion Widget
How to Download and View Images from the New Firebase Storage
Cannot Access Appdelegate While Testing Xcode Project
Extending a Delegate from a Base Class
Dyld: Symbol Not Found: _Tmpdcss12Anygenerator
Expand Uitextview and Uitableview When Uitextview's Text Extends Beyond 1 Line
Custom Mkoverlayrenderer Drawmaprect Function Not Drawing Polygons
Find Delegate in a Swift Array of Delegates
Using Avaudioplayer to Play Remote Mp3 File in Swift
Mapbox Navigation Pod Unable to Install with Objectivec Where I am Using Xcode 9.2