what is good practice using UIAlertView with UIActivityIndicator - iphone

I've read a lot here about misusage of UIAlertView and the fact that Apple may reject an app where UIAlertView is overused.
In my app I'm writing I have to update data rarely via online request and recalculating internal data structures. While this is in effect and running in a second thread I don't want that the user touches the GUI and the app's current settings etc. So I decided to show an UIAlertView with UIActivityIndicator and a UIProgessView for some seconds which is dismissed automatically when background work is done.
Do you think that it is a reason against HIG rules? If so do you have suggestions for good practice on this kind of work flow?
Cheers,
Konran

Instead of a UIAlertView, I'd use MBProgressHUD. It looks nicer and has a built in activity indicator. Apple uses a similar component in some of their apps.
https://github.com/matej/MBProgressHUD

I don't think an alertView should be used to stop a user from interacting with the screen. What you can easily do is add a "mask" on top of your content. Create a view; give a background color of .5 alpha black, and add it as a subview of your main view. This will dim everything else, and stop the user from interacting with it.

I have used an alert view with integrated activity indicator in a couple of apps and none of them was rejected from entering the AppStore. If you don't display any button inside the alert view the user won't even consider it as an alert view, so I don't see any problem with that.

Related

What is a UIGobblerGestureRecognizer?

I have just a regular UITableView, and I ran this code:
UITableView *tableView = [[UITableView alloc] init];
for(UIGestureRecognizer *gesture in tableView.gestureRecognizers)
{
NSString *className = NSStringFromClass([gesture class]);
NSLog(#"ClassName:%#", className);
}
One of the output lines is: ClassName:UIGobblerGestureRecognizer
Surprisingly Google has nothing on this. Anyone have any idea what it is?
Most likely this is an internal class that Apple uses. I've come across custom subclasses of UIGestureRecognizers that Apple created for some specific use. I'm sure they have needed to create custom gesture recognizers for various reasons, just as I have and not all of those classes are exposed for us to use.
Check out http://oleb.net/blog/2013/02/new-undocumented-apis-ios-6-1/
BJ Homer believes UIGobblerGestureRecognizer is used to avoid
recognition while animations are in progress. Otherwise, it’s
inactive. In an interesting Twitter conversation, Filippo Bigarella
and Conrad Kramer discovered that UIGobblerGestureRecognizer can
“gobble” touches in order to prevent other gesture recognizers from
receiving them in certain situations. What situations those are, I
don’t know.
I'm very sure it is used to prevent normal interaction while a particular cell is showing a delete confirmation button, and recognise any touch down as triggering that cell to return to a non-editing state.
It has this method and I'm assuming that excludedView is the cell that is showing a delete confirmation button, since you can normally still interact with cells in this state.
- (id)initWithTarget:(id)arg1 action:(SEL)arg2 excludedView:(id)arg3;
https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIGobblerGestureRecognizer.h
In short, from what I've read and what my experiments have shown, the "gobbler" seems to gobble up the swipes and touches on a table view (actually table cells) when a state transition (initiated by the user's touch or swipe) is in progress, so that the state transition can be completed before the user can touch the table again. Apple may use it in other cases but it is on the table view that I have observed the gobblers.
Now the long story: Suppose your table view implements a "drawer" on the table cell, like Apple's mail app or message app. When you open the drawer with a back swipe and take an action on any of the buttons in the drawer, all is well. But if you just close the draw with a forth swipe, you'll likely find that your next back swipe on a random cell doesn't work. But if you keep doing the back swipes, the next swipe usually will work again to show the drawer. Simply put, if you just open and close the drawer on random cells by using swipes, you'll find sometimes the drawer doesn't open.
I see this behavior on my table and thought I did something wrong. I tried many things and eventually implemented my own subclass of UITableView which also supports UIGestureRecognizerDelegate. In my subclass I implemented the delegate's shouldBeRequiredToFailByGestureRecognizer function, just to print out the gestureRecognizer and otherGestureRecognizer pairs. Then I found that when the back swipe is recognized, the gobbler is NOT present in the pairs. But when the back swipe is not working, the gobbler definitely IS present.
The general opinion on the web is that the gobbler is used to prevent the user from causing another state transition on the table while one transition is already in progress. That is fine if the user indeed takes some action (by touching a button in the drawer). But when the user just closes the drawer, the gobbler should be cancelled. Or the gobbler should be added ONLY when the user takes an action. After my realization, I went on to try my theory on Apple's apps. I already knew the Mail app behaves perfectly responding to every swipe. But the Message app behaves intermittently to repeated drawer opening swipes, much like my app. So I guess the developers of Mail are more careful and used internal knowledge to get it right. My observation is done on iOS 8.4 on iPhone 6 and iPad 2. And I believe the same gobbler issue dates back at least from the first iOS 8 release because I know my app had the issue from day 1 (months ago) but I just got around to look into the problem.
it should definitely be part of private API ..
i will suggest to stay out of it

in app purchase pop-up is clickable even when 'beginIgnoringInteractionEvents" is active

I'm showing custom indicator when user clicks a button to purchase an in-app item.
The custom indicator calls 'beginIgnoringInteractionEvents' on init.
However the apple provided in-app-purchase popup(to show item name/price) is still touchable.
Well, that's all good, but I tried adding another UIAlertview on the process(after user confirms the purchase and apple validates it), because the purchase process takes a while and it just seems boring with only being able to see indicator spinning.
Now the problem is, the UIAlertView I added is not touchable.
How is apple's alertview(in-app-purchase pop-ups) touchable and not mine?
The in app purchase box seems to count as a different process, separate from your app as it calls applicationDidBecomeActive: and applicationWillResignActive: similar to the text message box.
This would explain why it can receive touches, but views internal to your app can't

AVFoudationFramework: StillImageCapture: how to exit from AVFF?

I have a question or two about using AVFoundationFramework in XCode.
I downloaded AVCamDemo source code. I am trying to leverage the code in my app to replace UIImagePickerController (because it is slow) with the AVFF functionality. However, I cannot figure out how to exit the AVFF code when "Done" button is tapped in the UI. My app will provide the Done button.
Specifically, I need to know:
What do i need to stop the capture session? Just [session stopRunning] ??
My app's ViewController will invoke the AVFF, and will provide the "Done" button in the view controller that I will create for the AVFF functionality. When the user taps the "Done" button, I need to stop the capture process and exit back to my app. I am not sure how this can be done.
Any help will be highly appreciated.
Regards, Sam.
Yes. Although you may also want to ensure you turn the video torch off if you had turned it on, and if you called lockForConfiguration on the device you should be sure to unlock it.
There is no "exiting". If you presented your view controller using presentModalViewController:animated:, use dismissModalViewControllerAnimated:. If you pushed it onto a UINavigationController, pop it back off. If you did it some other way, dismiss it in the way appropriate for that method.
regarding your question on AVFoundationFramework:
I don't exactly understand what you are not succeeding to do. Some general options:
[session stop] will stop capturing.
You can play with the AVCaptureVideoPreviewLayer layer - that's what actually shows the camera preview.
All the ui code is in AVCamViewController - so you can just pop it from the stack, or remove it from superview - which ever is correct in your code.
If these don't help, please try to elaborate further on the problem, and perhaps supply some code.
Cheers,
Oded.

(iphone) show custom activity indicator?

I've made a custom activity indicator (actually just an imageView)
When user clicks something and I expect it will take a bit long to process(alloc a UIViewController and push on to navigation stack),
I alloc the indicator and add it as subview of current view just before the lengthy process starts.
Strange thing is, indicator doesn't show up until the push (left-right) animation starts.
Is it because the lengthy job takes the system, and ui drawing for activity indicator is delayed?
Am I doing something wrong here?
Thank you
Edit
Looks like I can do the "push" in background.. i'm trying it now
IPhone SDK - Leaking Memory with performSelectorInBackground
Is your job synchrone or asynchrone ?
If it's the first case, then it can be the problem.
Check all the method like :
[ self performSelector:<#(SEL)aSelector#> ];
You can thread this to avoid your [potential] problem.
Good luck.
You should process your lengthy tasks in the background. The UI won't update if you block the main thread.
So you have to refactor your app, the alloc and push of the viewController should happen within the blink of an eye, because you can't do this in the background.
But you can do the processing (downloading data I guess) in the background.
There is plenty information available about background processing. The way to go varies heavily on what you want to do exactly.

UIAlertView disappears when app goes to background and come back to foreground

I am developing an iPhone application (iPhone with multi tasking support) in which I am displaying UIAlertView on error. When UIAlertView is about to get display my app is sent to background. Now, if I try to get my app in the foreground, UIAlertView gets displayed for a moment and gets dismissed automatically even if I don't call dismiss/click on any button.
Does anyone knows what the problem is?
Thanks and Regards,
Deepa
When you add an alert view, it is added on top of the view of the current viewcontroller and while coming back to foreground , sometimes the view is reloaded from the xib and all the contents are refreshed. I suggest you to maintain a state variable in controller which calls the alertView again when coming back to foreground.
Rajact answer is good if by 'call' means the next
[theViewWhenYouAddedIt bringSubviewToFront:theViewWhenYouAddedIt.theAlert];
This worked for me
I hope this helps someone