Slow performSegue in tableview didSelectRowAtIndexPath - iOS12 - swift

Has anyone experienced this? I'm, not 100% certain that this is iOS12-related but calling performSegue inside didSelectRowAtIndexPath has a delay of like 1-2 secs.
I already tried different things that I found elsewhere like bringing it to the main thread but nothing works. Not sure if this is a bug or not but I haven't seen anyone talking about it online.

Try your code inside main thread:
DispatchQueue.main.async{
self.performSegue(withIdentifier: "YourSegueName", sender: self)
}
This worked for me, As sometimes we can not get e main thread which is important if you are working with some UI stuff.

Are you using the prepare Method? if so, what are you doing before the Segue?
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ExampleSegue" {
let ChangeVC = segue.destination as! ExampleViewController
...
}
}
Have you tried to hand over the index path of your selected Row to a different ViewController? And decide there what to do?

Related

How do I close the first window when the next one opens?

Xcode 9.2, macOS 10.12.6, Swift 4. I don't really know what I'm doing, so please explain what to do in detail.
I am trying to make it so that the first window is closed when the second one is opened. The buttonCONTINUE makes the second window open, via show segue.
I followed the Control+Click and drag as explained here, and tried to make the CONTINUE button close the first window when closed in two different ways; with self.view.window?.close() and with setting the key equivalent to CMD+W.
I've tried the solution suggested here, but that did not solve my problem.
Edit:
I have two windows, one each goes to the other one. Here is the code:
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if segue.identifier!.rawValue == "SegueToWIR" {
view.window?.close()
}
//neither if or else if make this work
if segue.identifier!.rawValue == "SegueToWarning" {
view.window?.close()
}
}
The second if statement doesn't cause an error, but doesn't do anything.
Unlike UIKit's UIControl, AppKit only permits a single target-action per NSControl instance. You are attempting to use two:
The show segue.
The action method connection you created using the control + click & drag method.
The segue takes precedence. You can verify this by setting a breakpoint at CONTINUE(_:). You'll find that the action method never gets called!
So scrap the action method &, alternatively, use:
📌 Note: The below implementation is valid for Swift 4.2+.
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
// Note: For Swift 4, replace `segue.identifier` with `segue.identifier?.rawValue`.
if segue.identifier == "my-segue-identifier" {
view.window?.close()
}
}

xcode retain cycle not show in memory graph

I'm trying to understand how xcode debugging tool works in terms of detecting retain cycles.
I have a simple Parent and Child view controllers both holds references to each other.
And after executing app opening closing VC several time, when I open debugging tool it neither shows that there is an issue with retain cycle nor runtime issue.
Please find below the code example and attached screenshot of xcode debugging tool
class ViewController: UIViewController {
var child: ChildViewController?
#IBAction func open(_ sender: Any) {
performSegue(withIdentifier: "segueChild", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "segueChild") {
child = segue.destination as? ChildViewController
child?.parentVC = self
}
}
}
class ChildViewController: UIViewController {
var parentVC: ViewController?
#IBAction func close(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
[EDIT, the real answer]
I think you're simply misreading the visual debugger. Taking a closer look at your screen captures, those memory diagrams are actually categorized under Retain Cycles.
Note however:
To actually waste memory, you'll need to abandon all references to the parent UIViewController. As long as the parent remains accessible, both parent and child are accessible from somewhere, even though they have a retain cycle.
(If you replace the child VC with a new one, the previous cycle actually broken and replaced by a new one. By constantly updating the child VC property, you're not wasting anything either.)
Imagine (all arrows are strong):
V--------------------
RootWindow --> GrandParentVC --> ParentVC --> ChildVC --^
This is not a problem.
Now suppose we replace GrandParentVC. An unreachable cycle is created:
RootWindow --> ANewVC
V--------------------
ParentVC --> ChildVC --^

Give Values to Buttons - Swift

I was wondering if someone can help me with this. Right now when I click on the button 0 it will automatically take me to the 2nd screen for testing purposes. Now I want to give value to the numbers accordingly and when the number clicked is equals to the number on my label than it will show the 2nd screen. If not, the Question mark label will blink or change color. Thanks
Place this variable above viewDidLoad():
var chosenNumber: Int?
Attach your buttons to an IBAction like this one and in the storyboard make each of their tags equal to their face value.
#IBAction func aNumberButtonWasPressed(_ sender: UIButton) {
chosenNumber = sender.tag
performSegue(withIdentifier: "theSegueIdentifier", sender: nil)
}
Pass the number to the following view controller like so and then use that number to populate the label accordingly.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if let vc = segue.destination as? TheViewControllerYouAreGoingTo {
vc.theVariableYouWantToSaveYourNumberTo
}
}
If you want to know how to do something differently, just ask.
If you want to really learn swift well, I highly recommend taking this Paul Hegarty Course for FREE. Paul Hegarty Course
The first two lessons specifically will teach you everything you could want to know about proper swift syntax and building a calculator early on. It might seem slightly advanced, but that is why I have watched the course 3 times now. Every 3-6 months since I started learning Swift this has helped refine my skills.
EDIT
let thisString = label.text
let thisInt = Int(thisString)
thisInt will be an optional, so at some point you will need to unwrap it. You can use it however you want to and set it to another label like so:
anotherLabel.text = "\(thisInt)"

what replaces indexPathForSelectedRow in Swift 3?

In projects prior to Swift 3 - If I was looking to segue an indexPath from a tableController, I'd have a line of code like
let indexPath = self.tableView.indexPathForSelectedRow!
However, in Swift 3, I am unable to write this. I can't seem to find any documentation on Apple's site or other SO questions to find a workable piece of code.
In response to Frankie's comment, I went back to my code (here is all of the current segue Swift 3 code) and have tried to copy and paste above code snippet... but to no avail. Xcode does not auto complete if I enter "self.tableView". It does not recognize indexPathForSelectedRow! either. I'm missing something.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "dineSegue"
{
if let destinationViewController = segue.destination as? RestaurantController
{
let indexPath = DineController.indexPathForSelectedRow!
destinationViewController.restaurantIndex = index
}
}
}
I googled 'indexPathForSelectedRow Apple documentation` and was able to find the property reference for you as it was conveniently the first result.
https://developer.apple.com/reference/uikit/uitableview/1615000-indexpathforselectedrow
That being said, it's exactly what you posted in Swift 3.
self.tableView.indexPathForSelectedRow
Are you sure the "DineController" reference is to the actual UITableView
When I had this issue, my initial reference was to the generic class, not the actual table I had coded.

No Segue with Identifier Error in Swift?

I am trying to use the performSegueWithIndentifier function to to create a segue from one ViewController to the next. But, when I press the button with the UITApGestureRecognizer connected to it, the View shifts to the debugger panel.
Here is the error it is displaying:
ContaminateTargetViewController: has no segue with identifier 'showMasterChemistryViewController'
(I cut out the personal Info)
Here is the ViewControllers Class:
import Foundation
import UIKit
class ContaminateTargetViewController: UIViewController {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showMasterChemistryViewController" {
let chemistryMasterViewController = segue.destinationViewController as! ChemistryMasterViewController
}
}
#IBAction func showPlaylistDetail(sender: AnyObject) {
performSegueWithIdentifier("showMasterChemistryViewController", sender: sender)
}
}
I also previously had to manual segues from the 2 buttons I have on the ViewController and recently deleted them to switch over to the UITapGestureRecognizer for the convenience. I am wondering if I have an error in my code that I do not see or if previously deleting the manual segues from the View is causing this error. If the problem is rooting from the previously deleted manual segues please tell me how to fix this in your error. If the problem is rooting form the code, please leave the code I should add, delete, or substitute.
Any suggestions or input is greatly appreciated.
Thanks in advance.
This error is called when you do not have the requested segue connected to your view controller. Are you sure that you have the two view controllers connected via a segue named "showMasterChemistryViewController" on your storyboard?