How to prevent a UISwitch from changing state? - objective-c

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.

Related

show alert xcode and go back after alert

i want to show the alert and when somebody click on OK they need to be send to the page before. How can i make this?
I use the following code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"BOOYAH!"
message:#"Saved" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
Considering you have 1 option on the alert view and the delegate is self. Use this method in the same .m file as the code above
- (void)alertView:(UIAlertView *)alertV didDismissWithButtonIndex:(NSInteger)buttonIndex
{
//go back a page
[alertV autorelease];
}
Don't forget to release the alert view. I added it in the delegate method, but you can choose to release it right after showing it (only 1 release though)
Assign the UIAlertViewDelegate to self and then implement the following method is called
- (void) alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == buttonIndexForOK) { // Where buttonIndexForOK is the index for your ok button, in this case, that would be zero, but if you want an OK and a Cancel button this would be different.
// go back to the last page
}
}
UIAlertView follows the delegation design pattern that is extremely common in iOS development. You provide a delegate object, and when the object wants to tell you about something, it sends that delegate object a message.
In your code, you've provided self as the delegate. This means that this object needs to conform to the UIAlertViewDelegate protocol.
You will see that there are several methods you can implement to react to various events relating to the alert view. You should use the alertView:clickedButtonAtIndex: method, which provides an index parameter indicating which button was tapped.

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.

UIPickerView frozen when starts

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.

iPhone keyboard popup problem in UIAlertView

I want to accept password using an alert view. Following is the code I am using. But I am unable to figure out why does the keyboard pop out two times instead of once? Any ideas?
UIAlertView *passwordAlert = [[UIAlertView alloc]
initWithTitle:#"Enter Password" message:#""
delegate:self cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Submit",nil];
[passwordAlert addTextFieldWithValue:#"" label:#"Password"];
UITextField *textfield = [passwordAlert textFieldAtIndex:0];
textfield.secureTextEntry = YES;
[passwordAlert setTag:10];
[passwordAlert show];
Not entirely sure where addTextFieldWithValue is defined but you may want to check your .xib file to make sure you didn't place double views on the "stage" as in this post:
http://www.iphonedevsdk.com/forum/iphone-sdk-development/1479-uialertview-popping-up-twice.html
Also, check out this post. Looks like you may have to "tell the text field to become first responder before showing the alert view, you'll wind up with two keyboards":
http://www.iphonedevsdk.com/forum/iphone-sdk-development/2753-new-info-adding-text-fields-alerts.html#post14701