I have a UIButton that trigger the IAP process. There is some time (2/3s or more if internet connection is bad) before an alert view is displayed (either asking for id and password, or the confirmation one). So one may click several times, thinking that the button is not working. And then you get as much alert view in a row as times you clicked and they are shown even if I quit the app and I'm on another meanwhile. That's pretty annoying.
My solution so far is to set a boolean as property of the UIviewcontroller. If it's false, click does nothing, else click trigger payment process. I set it to false on first click and in viewwillappear i get it back to true. The problem is that to be able to click the button again you must leave view and come back to it. That's not cool...
So here is what I'm looking for ideally : a function that is triggered as soon as any alert view of any kind is shown or dismissed. Show is better because i could use that to stop an eventual activity indicator I'd like to add too.
Thank you for you ideas.
Don't base it on the alert view being shown (you can't anyway). Instead, when the button is pressed, disable it or hide it (and show your activity indicator). When you start the purchase, add your controller as the delegate. Use the delegate methods to update the UI to enable / show the button (or remove it all together if more appropriate) when you get the callbacks which tell you the purchase is complete / failed.
Related
I have an iPad app that uses a UIPopover from within a UIVIew; I need to show an alert-type message when a certain condition has been met.
The problem is using a UIAlertView from within the UIPopover, when the user taps on a button in the UIAlertView, it also dismisses the UIPopover, which defeats the purpose of the alert.
I tried using UIActionSheets, but they don't display at all, probably because they are not being called from a controller-type view.
Is there a way to circumvent this behavior?
No, and you shouldn't do that. Popovers are supposed to go away as soon as you touch anything else.
You could enlarge the popover slightly and make room for a status message. When the user creates an appointment that overlaps, you could display a message in the status area.
Or, you could dismiss the popover and display an alert with "ok"/"cancel" buttons. The OK button would create the overlapping appointment, and the cancel button would discard it.
You will need some place to save the info from the popover while you are waiting for the user to decide what to do with the alert. Perhaps have the popover pass a message back to the view controller it comes from, and then have the source view controller create the alert, set itself as delegate, and handle the responses from the user.
According to Apple's Human Interface Guidelines, it is OK to display a UIAlertView on top of a popover:
https://developer.apple.com/library/ios/documentation/userexperience/conceptual/MobileHIG/Alerts.html
To quote specifically:
On iPad, don’t display a modal view on top of a popover. With the
possible exception of an alert, nothing should display on top of a
popover.
Displaying a UIAlertView from a popover does not automatically dismiss the popover. There is likely some of your own code being executed which is causing it to dismiss. For example, in a similar situation I had, I found that displaying a UIAlertView was invoking "shouldAutorotate" in my split view controller, and (due to earlier iOS bugs) I had placed code there to dismiss the popover. For iOS7+ this was no longer necessary, so I was able to move this code into willRotateToInterfaceOrientation, where it no longer causes dismissal of the popover upon display of UIAlertView, because in this case, even though "autoRotate" gets called "willRotateToInterfaceOrientation" does not.
I'm dealing with a weird problem: I've got a UIViewController to handle a list of items to download via inapp purchase.
When a user choses the product to buy, all the purchase flow begins. At this particular moment, I push a UILabel and a progress bar to display the current state of the download.
If, before that, a user choses to go in another part of the application (i.e. by tapping an item form the tab bar menu ), the application continues the purchasing process from there (that is reduced down to saying yes to a couple of dialog boxes and inputing the itunes store account credentials).
The process (that is attached to a background thread) runs smoothly till the end of it, but if the user comes back to the store view the UILabel and the progress bar are not show, I mean, they are initialized and running but they're not visible.
Is there a right way to behave in that circumstance?
Do I have to force the refresh of the view, or do I have to remove'em from the superView and push'em back again?
thank in advance,
hope I'd be clear enough, otherwise don't be afraid to ask, I'll be glad to
explain myself in a more deep and clear way.
-k-
Without a code it is difficult to give you the exact solution.
A possibility is that when you moved out from the original UIViewController the system did unload the view on that controller. It is possible that with this unload the progress bar and label were not destroyed (because over-retained by your view controller or not nil-ed in the viewDidUnload method) but when you entered in the view controller again the view was reloaded from scratch (typically from the nib) with new progress and labels.
So it is correct that you retained the progress bar and label (even if there are better ways to achieve the same result) but you must add them to the view controller view in the viewDidLoad method. A typical way to do this is to store a "active" progress bar in a dictionary and when the view is reloaded from the nib it must be added to it. As soon as the download finish you can remove the progress from both the dictionary and the view. There are other ways to accomplish the same result, so my suggestion is just to give you an idea.
So in order to see if my answer is correct, you must check the viewDidUnload method, add a breakpoint on it and see, once it has been triggered and when you come back to your original view, if the progress bar has disappeared or not.
Hello Holographix u havnt posted any code so it would be difficult to tell
well it seems like the object of Uilabel and progress bar are getting released the time u comes back to the view.
Im looking for some help regarding to put a save like confirmation if some changes where made to a UITextField and UISegmentedControl.
Can I prevent the UINavigationController from pop the view? And then pop based on buttons in a AlertView?
I use the UITextField and UISegmented control to POST data to a webservice.
I perhaps need to use a modalView for this? but wanted first to see if someone have another idea, because I would like to keep navigation clicks down if possible.
Any suggestions for this?
Thanks,
Why not just using a UIAlertView?
EDIT: On second thought, and re-reading your question + comment, I would recommend to use a Modal View with classics OK/Cancel buttons + a UIAlertView(s) for confirmation(s). (UIAlertView "poping" on OK/Cancel is easy to do via UIAlertViewDelegate)
That's what Modal views are for, block UI until some user action has been completed. Like a form. This is how I do all my forms, and how Apple does (just look at the create mail screen for an example, or any form of iOS apps)
Adding a "Magical" action requiring user interaction on the back button of a navigation controller is bad in terms of user experience, if you hit back, you expect the view to pop, nothing else. I would then be surprised if Apple SDK even allows to cancel that event...
You can do what you would like without the need of a modal view.
First, you can use your text field's UITextFieldDelegate to set a flag in your controller when the field content is modified. You can reset this flag when the data is sent out.
Then you could override your UIViewContorller's viewWillDisappear to show an alert to the user in case new data have not been posted at the moment the view is going to disappear and give him the possibility of sending it to the server. This method will be called when you move to a different controller in your navigation UI, and you will not have a chance to "reject" the operation.
I am writing a notification system just like growl. The notification is a window and it's level is set to NSModalPanelWindowLevel. The only problem is, I have a button in that window and when the user wants to click that button, he/she has to click it twice. But, for example, in growl, no matter what window you have opened, you just simply click the notification and it registers a click.
So is it a level problem? If so, what should I set it to? Thanks
In your custom controls that make up the view content of the window, you will likely want to override NSView's -acceptsFirstMouse: method to return YES:
Discussion
The receiver can either
return a value unconditionally or use
the location of theEvent to determine
whether or not it wants the event. The
default implementation ignores
theEvent and returns NO.
Override this method in a subclass to
allow instances to respond to
click-through. This allows the user to
click on a view in an inactive window,
activating the view with one click,
instead of clicking first to make the
window active and then clicking the
view. Most view objects refuse a
click-through attempt, so the event
simply activates the window. Many
control objects, however, such as
instances of NSButton and NSSlider, do
accept them, so the user can
immediately manipulate the control
without having to release the mouse
button.
Not sure if this is what Growl does, but you might be able to listen for mouse over events in the window and use them to activate/deactivate the window prior to the click. I suspect your issue is that the first click is being eaten by the activation of the window.
Just a guess on that though.
To learn how to handle mouse over events, check out this documentation:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/TrackingAreaObjects/TrackingAreaObjects.html
I have a List in my smalltalk application that gets updated by user events. The list updates correctly, but it only redraws, repaints, or refreshes whenever the window is forced to redraw. So it'll appear as it is supposed to, but only when I hide and then reshow the window, or drag it off screen and then bring it back on.
How do I make the App window automatically redraw, whenever the list is updated?
I got this working by including:
self changed: #objectInList
In the method of the objects being changed.