I have noted recently that each of my app view has one particular bug/behaviour: if user taps too fast on a UI component when the view appears, the tap is simply ignored. If the user wait a bit before tapping, the tap works.
Storyboard is used for the storyboard, tap gesture recognisers are on UIImageview and using IOS 10.2.
Through different forums i have read about the following options:
nest the call of "present view controllers" in main thread
Call CFRunLoopWakeup before presentviewcontroller
Add programatically the TapGesturerecognizer
change the states of "delays touches end" and "delays touches began"
disable 3d touch option as similar symptoms was reported to happen in other apps
All above have been unsuccessful.
Anyone would have met similar issues with the first tap just after the view load?
[Update: I realise this misbehaviour is not specific to this app. Two tests to try:
create an xCode Project for iPhone and two view controllers Controller A and Controller B. Two buttons : a button on Controller A view to go to Controller B view and a button Back in Controller B view to go back to Controller A view. Tap to go from View A to B, tap back in B and try immediately to tap on button to go to B. First tap doesn't work either.
Go in Settings of the iPhone. Tap On Notifications. Press On Settings to go back to Main Settings screen, Tap immediately back on Notifications. If fast enough, first tap doesn't work. Second tap works or waiting a bit before first tap.
Question is now: this looks like a common problem across iPhone apps. Would you know if there would be a common setting somewhere? or is this a common bug for given IOS version ?
]
Stephane
This is a general problem (the moment when the view controller is changed, the first tap will be ignored), but this is not a bug that will happen only because the switch view controller's animation has not yet been completed. If you set the animation to false , then the view controller can immediately respond to your click, no matter how fast (anyway faster than your hand) :)
Related
I have noticed a problem with the navigation in our app.
Back buttons on UINavigationController for dismiss a viewController, or ok button for dismiss keyboard not reacting on tap each time. I have to press several times to finally enter in the button action method.
But i can see the button hilighting on each tap.
My viewControllers are pushed/presented and dismiss from the main thread.
My viewControllers is pushed/presented once.
There is no hidden view who catch the tap.
In the memory graph, I have no viewController instance leacked.
In the instrument I Have no CPU hight usage, No network call in progress.
App is in swift and uses rxSwift.
We don't use segue, all screens are pushed programmatically.
Has anyone ever encountered this problem ?
Have you something for me to check, explore or some advices ?
I have resolved my problem. It was caused by an override of isEnable method in a UIButton extension for my buttons.
I had changed the isUserInterrationEnable accordingly to isEnable.
Back button in navigation controller and ok button in keyboard InputAccessoryView are also UIButtons.
So my extension makes conflict with the system behavior and makes systems buttons not working all times.
removing isUserInterractionEnable in the isEnable override solve this problem.
This question already has an answer here:
Swift 4 Odd unexpected jump back to earlier storyboard
(1 answer)
Closed 4 years ago.
Every time I tap somewhere along the top part of a view controller, it would return to the previous view. Root Controller is not affected as it doesn't have anything to return too. All of my View Controllers are affected though. (Please read update 3)
Things I've tried:
Looked for unnecessary gesture recognizer. (Result: I received nil when I check for the list gestures.)
I figured I might have accidentally added or left a IBOutlet to the view or something. (Result: There was no unnecessary IBOutlets.)
I disabled user interaction from a view to see if it would be affected. (Result: The bug seemed to go away until I enabled user interaction again.)
I've tried to do some research but I wasn't getting the results I wanted.
Tapping above the green line will make the View Controller return to the previous Controller.
I'm still relatively new to Objective-C and Xcode so I don't know if I'm making a rookie mistake or not.
UPDATE (Please read update 3)
Still nothing but here are a few more things i've tried:
Logging every user action.
Created a new project with new view controllers.
Opened a previous project to test it's view controllers.
Uninstalled and reinstalled Xcode.
All attempts still came with that weird bug.
UPDATE 2(Please read update 3)
I've decided to put a band-aid over the problem. Since the bug doesn't work when clicking over a button, I put constraints on a empty button, put it on top of the background image and removed the effect when button is tapped.
I thought this would work but there is a few spots on the screen that activates the bug. I experimented and figured that certain parts of ui elements activated the bug. (Example: Some labels in a Stackview, top part of a textfield, a switch, top part of a UICollectionView, etc.)
I've disabled user interaction for certain ui elements. Unfortunately not all ui elements could be disabled because some require user interaction.
Also I figure out that tapping with three fingers on the screen somehow activates the bug.
Here is an error code I received in the console when I was trying multiple taps on the screen:
<_UISystemGestureGateGestureRecognizer: 0x2822fc1e0>: Gesture: Failed to receive system gesture state notification before next touch
UPDATE 3
After playing around with the code again. I believe I've figured out what is causing the problem but not how to fix it.
I believe it has to do with the story board segue, or at least the transitions being used. If I set the kind to "Show(e.g. Push)" than it works fine, but if I set the kind to "Present Modally" and the transition to "Partial Curl", the bug does it's thing.
Sidenote: This is how I tested it. I created a new project (I don't think the language matters). The project has two view controllers; one button each with segue pointing at each view controllers. Segue 1 has it's kind as "Present Modally" and the transition as "Partial curl". Segue 2 is on the 2nd view controller and has it's kind as "Show(e.g. Push)". To test the bug, tap along the top part of the screen. If the bug worked, then it should show the partial curl transition but in reverse and send the user back to the 1st view controller.
maybe you are experiencing the standard swipe back gesture coming from the navigation controller. It thats the case try this code:
Objective-C:
if ([self.navigationController respondsToSelector:#selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
Swift:
navigationController?.interactivePopGestureRecognizer?.isEnabled = false
Currently I'm running into an issue where there are table cells that allow for touch events to get there details. However, if the user presses the cell 2-4 times within 1 second it causes multiple view pushes onto the navigation view controller. This causes obvious errors when the views are popped off and the navigation controller has trouble going to a sub view and coming back. Leading to multiple traps, most unfortunately don't come with a error log. However, since this behavior shouldn't be supported in the first place. The question is besides thread locking is there other ways to prevent multiple touch events on either UiButtons or on table cells?
--Side Info--
Side information you may want, I am working with Xcode Version 6.4 due to the https vs http security settings added in Xcode 7. If later versions of Xcode automatically implement solutions to this then that would be good to know as well. Thank you for you help.
You can lock a button (or cell) after it tapped:
button.userInteractionEnabled = NO;
or whole interface:
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
and unlock when transition/loading is done.
If you don't want to throttle the touch events with GCD, both UIButton and UIGestureRecognizer exposes an enabled property. You can simply disable the button after one touch, and re-enable it after you've pushed the detail view controller.
An easy way to re-enable it would be in the viewWillAppear method of the controller pushing the detail view--that way the enabled property would be automatically reset whenever you went back to that view controller without having to listen to UINavigationController transitions, etc.
i have two View Controllers in my project, the first one is for Sign Up view and the second one is for Sign In view. In the first view i have a sign in button which has a segue to the second Sign In view (i.e. if you've an account pass to Sign In view, please see attached image).
Unfortunately, when i clicked sign in button in Sign Up view the second view(Sign In view) not opening.
I'm sure prepareForSegue is called and the button touch is certainly processed(IBAction for the button is called). Also ViewDidLoad of the view supposed to open is called, as you may guess ViewDidAppear of the same view is not called.
In a nutshell, what happens is button and segue is working and the second view is loading but it does not appear and the first view does not disappear. It happens all of a sudden(i.e. it was working properly before), i do not know what did happen or what i did mistakenly. If anybody can help me, it would be a great relief.
*I know, in this case IBAction and prepareForSegue are not necessarily to be used, these were used just to make sure that the button and the segue are working properly.
I have added state restoration to my app, and it seems to work fine, however I'm not happy with the way that it functions.
Basically, the app is a Disney wait time tracker, so it has a selection of the four parks when you first open the app. Tapping on one of these parks segues (with the slide up animation) to the main section of the app. The problem is - When the app is reopened and the view restores after a few seconds, the slide up segue is performed (which is quite distracting).
Anyone have any idea why that is happening?
It might be down to how you are triggering your view and what time of segue you are choosing.
Otherwise you can specify whether its animated in your segue method:
ObjectiveC
[self.navigationController pushViewController:aYourViewController animated:NO]
or in Swift:
self.navigationController?.pushViewController(yourController, animated: false)