UIPickerView frozen when starts - objective-c

I've got a strange problem, I managed to blend UIActionSheet together with UIPickerView and invoke them both from UITextField, but the problem is that in order to use UIPickerView I have to click/tap on "Done" button first. Then, the picker view becomes usable. But, initially, when the picker view appears, it is frozen and unusable - the wheel doesn't move. Only after I tap on "Done", the background gets more transparent, I can see in the background the other UITextFields that I added to the scrollView, and I can move the wheel at that point. So to move the wheel I need to first tap on either "Cancel" or "Done", it's frozen when it appears at first.
Here's my code (some of it is from researching)
myPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0,185,0,0)];
myPicker.delegate = self;
myPicker.showsSelectionIndicator = YES;
UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:#"Title" delegate:self cancelButtonTitle:#"Done" destructiveButtonTitle:#"Cancel" otherButtonTitles:nil];
[menu addSubview:myPicker];
[menu showInView:self.view];
[menu setBounds:CGRectMake(0,0,320, 700)];
[myPicker release];
[menu release];
The solution I thought of is to automatically make "Done" be tapped first time so user doesn't have to tap on "Done" to use the wheel and then tap on "Done" again when selection from the wheel is chosen. But I'm not sure that's the right approach.
I also tried to make it:
[menu showInView:scrollView];
But the result was the same - wheel doesn't move.
Anybody knows how I should solve this?
Thank you,
Victor.

There's no way your app will be approved if you misuse UIActionSheet in this way, and it's not designed to work in this way, and (as you've found and as I've found when I once tried it) it does funny things when you try to use it in this way. So it's not work the effort to get it working.
You should use a standard full screen view containing your picker and then use presentModalController:. You could alternatively manually add the picker as a subview of your main view, if the intention is to have it as an overlay.

Related

Why is my UIActionSheet hidden by my TabBarController?

I am having a problem correctly implementing a UIActionSheet in an iPad 5.1 (XCode 4.3) project. I can populate it correctly with all the items I need. The list is longer than the window, but the scrollbars automatically come up, etc. However, the cancel button (which I presume is supposed to be at the end) is coming up half hidden behind my tab bar. Shown below:
(sorry, SO won't let me post images yet)
Here is my storyboard setup:
The entry point is that Tab Bar Controller on the left, which goes to another Navigation Controller (center), which has the View Controller on the right as the root view.
http://i854.photobucket.com/albums/ab103/srVincentVega/ScreenShot2012-06-28at52713PM.png
I have tried presenting the UIActionSheet in all sorts of ways, but this odd behavior persists, and I can't figure out how to address it
- (IBAction)cmdReason:(id)sender
{
NSArray *reasons = [AppState getInspReasons];
UIActionSheet *action = [[UIActionSheet alloc]
initWithTitle:#"Reason for Inspection"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:nil];
for (NSString *rsn in reasons)
{
[action addButtonWithTitle:rsn];
}
[action showInView:self.view];
}
I have tried the various methods to show "action" - showFromTabBar, showFromToolbar, etc - I am VERY new to this development environment, so I am not up to speed yet on how these items interact at this level. Does anyone have a suggestion for how I can present this correctly?
I am sorry if this has already been asked elsewhere. I have spent all day trying bits of code from all over the web, including SO. I don't know if it's something to do with my storyboard layout, or what.
One further thing - when I rotate the emulator, the action sheet does redraw, but the bit at the end there gets wonky looking, like it can no longer figure out how to draw it.
Many thanks!
EDIT:
I have put together a very small project that demonstrates this exact behavior. I don't have a good way to host the zip file, so I put on google docs and shared it. The link is below. If you click on that, there should be a download option under file that will give you the original zip file.
https://docs.google.com/open?id=0B7IYvy9_c_NLaEFneGc5bzc2S2c
Seems like there is not a real solution for this. It looks like it's a limitation with UIActionSheet if you add that amount of button titles and present that from a tab bar.
Beside that, the proper way to display an UIActionSheet from a tab bar is to use
[action showFromTabBar:self.tabBarController.tabBar];
instead of
// Taken from your example project
AppDelegate *d = [[UIApplication sharedApplication] delegate];
UIWindow *w = d.window;
UIViewController *vc = w.rootViewController;
UITabBarController *c = (UITabBarController *)vc;
UITabBar *t = c.tabBar;
[action showFromTabBar:t];
I would think if you got a reference to the tab bar controller then you should be able to present it from that. You can try showing it from the main window but I would think you shouldn't rely on that.
[action showInView:[[UIApplication sharedApplication] keyWindow]];
Try this:
CGRect r = CGRectMake(x, y, w, h); //change values to fit location of button
[actionSheet showFromRect:r inView:self.view animated:YES];
I used it on one of my apps with the same problem and the dismiss button showed up ok.

How to prevent a UISwitch from changing state?

I have a UISwitch that is defined in an .xib file. The event that I'm connected to is "Value Changed".
I want the following behavior (essentially warning the user that this function is available in the Full Vesion of the software):
allow user to click on switch
prevent the switch from sliding to "on" (I want the switch to stay in the "off" position)
show an alert
So far, I can't get 2 to work. Right now I have a kludge. I force the switch to go back to the OFF position:
[self.switchButton setOn:NO animated:NO];
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Feature unlocked in Full Version" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil] autorelease];
alert.tag = ALERT_TAG;
[alert show];
The problem is that you see the switch slide to the ON position, then it jumps to the OFF position, and then you see the alert box.
Is there a way to intercept the behavior so that the switch doesn't slide to the ON position?
UPDATE
I tried to link up to the "TouchUpInside" event and have moved my alert code there. It's still not early enough to intercept the visual change in the state of the switch.
I've had the same problem like you. In your valueChanged action method you have to invoke the setOn method with animated set to true. So in swift that would be:
#IBAction func switchValueChanged(sender: UISwitch) {
sender.setOn(false, animated: true)
}
It might seem counterintuitive since this method is called after switch value changed. But somehow it seems to work.
One unsophisticated solution is just putting a button with the same size and transparent background color in front of the UISwitch control. While it is not the direct answer to your question, it is nice workaround and I always do that with UIImageView.
Why dont u simply set userInteraction to NO
[self.switchButton setUserInteractionEnabled:NO];
add a clear color subview to that UISwitch view, cover it and add UITapGestureReconizer to this subview, and all action operations can be triggered in tap action including change the UISwitch view status. Hope it help you!
Try to listen to the TouchDown event instead of TouchUpInside.
This is the way you do it, set UISwitch to .touchUpInside
switchBtn.addTarget(self, action: #selector(unlockEvent), for: .touchUpInside)
if you set to .valueChanged, will trigger the event every time, regardless having user interaction or not.
set the state of UISwitch to off in xib and inside valueChange action method
-(IBAction) switchValueChanged{
if (toggleSwitch.on) {
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Feature unlocked in Full Version" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil] autorelease];
alert.tag = ALERT_TAG;
[alert show];
}
}
its pretty lame that there doesn't seem to be a delegate method for UISwitch to check whether to allow UISwitch to change.
I added a button over the UISwitch and handled the switching on the button's IBAction event, seems to be the best method.

Popover not being dismissed when calling dismissPopoverAnimated or clicking once outside of popover

I hope someone can help me with this weird bug. I've got a popover with buttons to perform various actions. There is a toolbar item that must be clicked to bring up the popover. Here is the action method that is called:
-(IBAction)showActions:(id)sender
{
ActionsPopUpController* controller = [[ActionsPopUpController alloc] initWithDelegate:self state:DELETE_ENABLED | FACEBOOK_ENABLED | TWITTER_ENABLED | EMAIL_ENABLED];
_actionsPopUp = [[UIPopoverController alloc] initWithContentViewController:controller];
[controller release];
[_actionsPopUp presentPopoverFromRect:_actionButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
_actionsPopUp.delegate = self;
}
As you can see, I have a property/ivar (actionsPopUp) that retains a reference to the UIPopoverController. This is used later to call dismissPopoverAnimated when I want to dismiss the popover. Here is an example of it's use:
-(void)shareWishToEmail:(id)sender
{
[_actionsPopUp dismissPopoverAnimated:YES];
[[WishCloudService sharedInstance] showMailer:self withItems:[NSArray arrayWithObject:self.item] delegate:self modal:YES];
}
In this method, I dismiss the popover first, and then perform the action associated with the button that was pressed in the popover. Unfortunately, this doesn't appear to work. The action gets performed, but the popover is not dismissed. In addition, it doesn't seem to get dismissed when the user clicks once outside of the popover. But if clicked outside again, it does get dismissed. Another observation is that the first click seems to hide/dismiss the drop shadow of the popover, but not the popover itself. It's the second click that dismisses the popover. However, no amount of calling dismissPopoverAnimated seems to dismiss the popover at all.
I've swapped in UIPopoverControllers that seem to work in other parts of the application, but get the same results, which leads me to believe that it is something specific to the UIView/UIViewController that I'm presenting the popover in. I am creating the view programmatically rather than through a NIB. It escapes me at the moment why I decided to do that, but I don't believe that it should be relevant. Someone please let me know otherwise. Here is my loadView method:
-(void)loadView
{
self.view = [self createView:_item];
self.currentView = self.view;
_wishItemViews = [[NSMutableDictionary dictionary] retain];
[_wishItemViews setObject:_currentView forKey:[NSNumber numberWithInteger:_currentIndex]];
}
I have a currentView property because I need to be able to slide new views in and out, and I'm using CATransition animations to do it. The currentView property is used to swap the views when it performs the transitions. Again, not sure if this is relevant, but I'm including it for completeness and just in case it does make a difference. Hopefully, that's enough information for someone to help point me in the right direction. Or at least prompt some additional questions that might help me think this through. Any help would be greatly appreciated.
Another observation is that the first click seems to hide/dismiss the drop shadow of the popover, but not the popover itself.
It seems you have stumbled upon the rare double-popover. ;-)

UIAlertView with 19 buttons

I am creating a pop up dialog box (UIAlertView). It works great, except I need to choose from 19 items, and the buttons do not automatically scroll and only five fit on the screen.
So, can I make them scroll? If not, can I put a UIPickerView in an alert view? Or, is there a better way?
Code so far:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Provider"
message:#"Please choose your provider:"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"AT&T",#"Verizon",#"Sprint",#"Nextel",#"T-Mobile",#"Alltel",#"US Cellular",#"Virgin Mobile",#"Metro PCS",#"Boost Mobile",#"Cricket",#"Rogers(Can)",#"Telus(Can)",#"Bell Mobility(Can)",#"Fido",#"Virgin(Can)",#"O2",#"Vodaphone",#"Meteor", nil];
[alert show];
[alert release];
You might consider using a UIActionSheet instead. It will automatically scroll when you have a lot of items.
Don't create 19 buttons. Instead, use UIPickerView.
In general, use UIActionSheet or a modal view of some sort.
In this particular case, you may be able to use the CoreTelephony framework. CTCarrier has a property carrierName that is supposed to return the something similar to what you are asking for (as long as the device is connected to a cellular network).

iOS - Show UIActivityIndicatorView when table is being loaded

I have a tab bar application. I have 2 questions.
Using a default image for the
application does that enable the
application to initialize itself (the
first view that is showed in
MainView.xib) in the background while
the image is being displayed?
Touching the second tab in the
application, the application will
load data into a UITableView. This
takes some time (fetching some data
from the internet) so going from the
first tab to the second tab there is
a delay before the table is being
showed in the second tab. I want to
display a UIActivityIndicatorView while
the UITableView is being populated
and then want the
UIActivityIndicatorView to disappear
when the UITableView is finished
loading. How can I achieve this?
You can use this inside the activity:
protected Dialog onCreateDialog(int id) {
ProgressDialog progress = new ProgressDialog(this);
progress.setMessage("The information is gathered, one moment please.");
progress.setIndeterminate(true);
progress.setCancelable(false);
progress.setCanceledOnTouchOutside(false);
return progress;
}
This will show an alert once you call this in(or on) the activity:
showDialog(0x0001);
When the dialog has to fade out call this:
removeDialog(0x0001);
EDIT
Now for objective-c:
UIAlertView alert = [UIAlertView initWithTitle:#"a title" message:#"a message" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil]
[alert show];
if(alert != nil) {
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.center = CGPointMake(alert.bounds.size.width/2, alert.bounds.size.height-45);
[indicator startAnimating];
[alert addSubview:indicator];
[indicator release];
}
EDIT
Removing it is done with this:
[alert dismissWithClickedButtonIndex:0 animated:YES];
[alert release];
/EDIT
That worked for me:) it could be its not totally spot on becouse i changed some stuff in the browser to now thow company secrets etc xD :).
Feel free to ask stuff about it.
YES. Even if you don't give any default image, it will load the first view controller showing a black screen.
Display the activity indicator view in your second view controller's loadView. And, put all the loading code in your second view controllers viewDidAppear: method. By doing this, your second view controller will be displayed with the activity indicator view as soon as you press the second tab. And after the loading is completed, dismiss the activity indicator. This will give you a smooth transition from one tab to the other.