iOS strange bug with button and view change - objective-c

That's the first time i post on this site.
I explain, i have to work on an already advanced project in ios.
I'm new in objective-c and it's a quite strange language when you come from java.
I have a strange issue.
In the app there is a login screen, you put mail and pass, click on a button and you go on the main view. It's work perfectly.
What i want to do is autologin. I use keychains for that, store it, retrieve it, populate my user and pass with. It's works perfectly.
If my user click on the login button it's also work perfectly.
But if i call the function myself with the code, it doesn't change the view. I can't understand why.
I put here the code where i think the change is called.
if ([result isEqualToString:#"1"]) {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:Email.text forKey:#"email"];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Welcom back to FriendsCam!" message:#"Start sharing your video" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
//Email.text = nil;
//Password.text = nil;
UIStoryboard *MainStoryboard_iPhone=[UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
self.view.window.rootViewController=[MainStoryboard_iPhone instantiateInitialViewController];
So this code is in a function who is called by the functions called when the button login is pressed if all field are correctly fill.
It work when a user manually click on the button but not when i call the button's function myself in code but the alert "welcome back" of good login show in both cases. it's only the jump in the storyboard who is broken.
Can someone explain why ? It will be very kind.

Ok i find the solution.
I was firing my method to quickly, something related with loading time of the view i think.
I delay my call with a nstimer and all work perfectly.

Related

unwind or dismiss view controller not working. Xcode 6.4

I've been trying to make my pushed view controller dismiss or go back one once a confirm action has taken place. I read the many posts in stackoverflow on this subject (I've never done it before) e.g:
How to perform Unwind segue programmatically?
but had quite some problems. First of all, the ctrl drag from view controller to exit, didn't work though that seems to be a bug in Xcode 6, so I added the following workaround as advised and changed the class back and forth:
#interface RequestLessonViewController ()
- (IBAction)unwindToMyViewController: (UIStoryboardSegue *)segue;
#end
This allowed me to add in the segue from my action button to Exit. I also of course gave it an identifier (unwindSegue).
I then added the performWithSegueWithIdentifier line in my buttons code as follows:
- (IBAction)requestLessonAction:(UIButton *)sender {
// PUT CONFIRM POP UP IN HERE ???
NSLog(#"ADD A LESSON REQUEST TO LESSONS DATABASE");
UIAlertView *confRequest = [[UIAlertView alloc] initWithTitle:#"Lesson Request Submitted"
message:#"Congratulations"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[confRequest show];
[self performSegueWithIdentifier:#"unwindSegue" sender:self];
}
However my unwind is still not being kicked off.
Maybe this is still a problem due to xcode 6.4 and I need to use a different work around?
Anyway any help in this would be great
Thanks
I fixed this using this very useful and clear github from Bradley.
https://github.com/bradley/iOSUnwindSegueProgramatically
Basically I wasn't creating the following type of method on the viewcontroller I was returning too, but inside the one I was trying to exit from :-/ All clear now thanks.
- (IBAction)returnToStepOne:(UIStoryboardSegue *)segue {
NSLog(#"And now we are back.");
}

UIAlertView is not visible after bring app to foreground

I'm working on a some iOs project. In this project, i have a process:
User register himself in registration page
When he press "Register", another page is showed (via NavigationControler, with progress idndicator and 'Please Wait' message.)
After get response from server, some message in UIAlertView is show
When user press "OK" on alert, it's moved to next (when everything is ok), or previous (when something go wrong) page.
In most case, this flow works. But in sometimes (not always), when user send application to background/lock the screen while process indicator is on, and then turn app back to active state, UIAlertView is not shown. But, then, if user again send app to background and bring it back, message is visible.
Because interaction with UIAlertView is needed to continue, it's a problem. I cannot request from user a knowledge, that if no message is visible in this moment, they should turn app back and front again. I don't know why it is happen, and how to avoid this behavior. Can you help me?
When your app is in background you can give the local notification. so according to you if alertview is not coming but still you want that user should know about that something is happen or something is wrong then you can directly use local Notifications.
here is the code -
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = self.datePicker.date;
localNotification.alertBody = self.messageField.text;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = 1;
NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys:#"Object 1", #"Key
1", #"Object 2", #"Key 2", nil];
localNotification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[localNotification release];
So when local notification generate user can know about that. And you can navigate the user to directly to application. on clicking off local notification alert. locasl notification alert will come automatically.
here the link for the more details-
http://www.iostipsandtricks.com/ios-local-notifications-tutorial/

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.

UIAlertView "non-blocking" show message does retain the view?

I have a simple question for you... I was reading Beginning IOS 4 Development book and there is the following code example:
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#”Hello”
message:#”This is an alert view”
delegate:self
cancelButtonTitle:#”OK”
otherButtonTitles:nil];
[alert show];
[alert release];
Then it points out that the show message shows the alert view but the code does not stop it's execution until the user dismisses the dialog, it goes on and executes the following code... since next to the show message there is a release message, does the show method retain the view until it is dismissed? Otherwise I should not release it after the show message has been sent.. I'm sorry but I did not find this information on the reference pages, so I hope this is not a (too much) stupid question.
OT: how do I activate colors on code snippets?
The window that displays the alert view retains its reference, so you don't have to.
I've wondered this and concluded that something in the show method, likely a call to addSubview: increments the retain count on the UIAlertView preventing it from being dealloc-ed.