I would like to call my login method AFTER the keyboard was dismissed - since I want to start animation and change the UIView alpha to 0.5 until the response.
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == self.passwordText){
//hide the keyboard
[theTextField resignFirstResponder];
[self validateCredentialsRemotely];
}else{
[self.passwordText becomeFirstResponder];
}
return YES;
}
The keyboard is not being dismissed before the call to the method validateCredentialsRemotely and the screen freezes while the keyboard is displayed. I would like it to be dismissed first, and then call the method.
Use this notifications..
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
In keyboardWillHide method call your validateCredentialsRemotely method,This may solve your first issue
try this!
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
if (theTextField == self.passwordText){
//hide the keyboard
[theTextField resignFirstResponder];
[self performSelector:#selector(doAnim) withObject:nil afterDelay:0];
}else{
[self.passwordText becomeFirstResponder];
}
return YES;
}
- (void)doAnim {
//start animation
self.view.alpha =0.5;
[activityWheel startAnimating];
//validate user
[self validateCredentialsRemotely];
//end animation
[activityWheel stopAnimating];
self.view.alpha =1;
}
Related
This is my AlertView code :
- (void)initializeAlertControllerForOneButtonWithTitle:(NSString *)title withMessage:(NSString *)msg withYesButtonTitle:(NSString *)yesButtonTitle withYesButtonAction:(id)yesButtonAction
{
UIAlertController * alert = [UIAlertController
alertControllerWithTitle:title
message:msg
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* yesBtn = [UIAlertAction
actionWithTitle:yesButtonTitle
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * action) {
if (self.activityIndicator.animating) {
[self.activityIndicator stopAnimating];
}
if ([title isEqualToString:#"Wrong Password!"]) {
self.editTextField.text = #"";
[self.editTextField becomeFirstResponder];
}
}];
[alert addAction:yesBtn];
[self presentViewController:alert animated:YES completion:nil];
}
I am trying to fire this alert in my NSNotificatoin Response method. My Notification Response code :
- (void)receiveSMSVerificationResponse:(NSNotification *)notification
{
SMSVerificationDigitClassModel *smsVerificationDigitClassModel = [[SMSVerificationDigitClassModel alloc] init];
smsVerificationDigitClassModel = [notification object];
if (smsVerificationDigitClassModel.viewControllerName == ViewControllerNameProfileInfoEditViewController) {
if ([self alreadyRegisteredPhoneNumber:smsVerificationDigitClassModel.phoneNumber] == YES) {
NSLog(#"jogajog");
[self initializeAlertControllerForOneButtonWithTitle:#"Already Registered!" withMessage:kAlreadyRegisteredPhoneNumberMSGForChangePhoneNumber withYesButtonTitle:#"Ok" withYesButtonAction:nil];
} else {
if ([AdditionalClasses internetConnectionCheck] == YES) {
self.userModelClass.phone_number = smsVerificationDigitClassModel.phoneNumber;
[self updateUserModel:self.userModelClass];
} else {
[self noInternetConnectionAlert];
}
}
//Check if that phone number is already used
// udate phone numner in server
// update phone number in core data
//[self goToSignUpViewControllerWithPhoneNumber:smsVerificationDigitClassModel.phoneNumber];
}
}
I check it from break point, this line [self initializeAlertControllerForOneButtonWithTitle:#"Already Registered!" withMessage:kAlreadyRegisteredPhoneNumberMSGForChangePhoneNumber withYesButtonTitle:#"Ok" withYesButtonAction:nil]; is actually calling, but the alert view is not popping up. It says:
"Warning: Attempt to present on whose view is not in the window hierarchy!"
I have tried to add notification observer methods :
- (void)addNotificationObserver
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receiveUserModelResponse:) name:#"sendUpdateRequestToServerForPhoneNumberWithUserModel" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receiveSMSVerificationResponse:) name:#"SMSVerificationForPhoneNumber" object:nil];
}
In viewDidLoad, viewDidAppear & in viewWillAppear and removeObserver in dealloc,
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"sendUpdateRequestToServerForPhoneNumberWithUserModel" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"SMSVerificationForPhoneNumber" object:nil];
}
but it is not showing at all. So, how do I change my window hierarchy! in this viewController. If you understand, please reply back. A lot of thanks in advance.
Call the initializeAlertControllerForOneButtonWithTitle method inside a main queue dispatch queue block.
All UI operation should be on main threat.
dispatch_async(dispatch_get_main_queue(), ^{
[self initializeAlertControllerForOneButtonWithTitle:#"Already Registered!" withMessage:kAlreadyRegisteredPhoneNumberMSGForChangePhoneNumber withYesButtonTitle:#"Ok" withYesButtonAction:nil];
});
My question is :
When I write a user login UI, because the keyboard hide the password textfield, so I write some code to scroll up the login UI, but when the keyboard is hidden and the UI is scrolled to the old position, I find I touch the textfield which I can't get any response.
registe notification:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillshow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillhide:)
name:UIKeyboardWillHideNotification
object:nil];
_username.delegate = self;
_password.delegate = self;
will show keyboard code:
- (void) keyboardWillshow:(NSNotification *)noti
{
NSDictionary *userInfo = [noti userInfo];
NSValue *keyValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardRect = [keyValue CGRectValue];
int height = keyboardRect.size.height;
userInfo = nil;
keyValue = nil;
[UIView animateWithDuration:0.5f animations:^{
self.containView.frame = CGRectMake(0, -height+20, WIDTH/2, HEIGHT/2-20);
}];
}
will hide keyboard code:
- (void)keyboardWillhide:(NSNotification *)noti
{
[UIView animateWithDuration:0.5f animations:^{
self.containView.frame = CGRectMake(0, 20, WIDTH/2, HEIGHT/2-20);
}];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[_password resignFirstResponder];
[_username resignFirstResponder];
}
Could some one help me? I use the storyboard to write the code.
I use a MPMoviePlayerController to play a video from Internet.
player = [player initWithContentURL:[NSURL URLWithString:videoURL]];
player.view.frame = CGRectMake(0, 0, videoView.frame.size.width, videoView.frame.size.height - 20);
[player setControlStyle:MPMovieControlStyleEmbedded];
player.scalingMode = MPMovieScalingModeAspectFit;
[player prepareToPlay];
player.shouldAutoplay = NO;
[videoView addSubview:player.view];
I notified that after I clicked the full screen button (2-arrows-button), I was navigated to the full size video screen. I couldn't restore down the screen by touching the Done button. I even used NSNotification but can't resolve the problem. Here is the Notification code:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieEventFullscreenHandler:)
name:MPMoviePlayerWillEnterFullscreenNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieEventFullscreenHandler:)
name:MPMoviePlayerDidEnterFullscreenNotification
object:nil];
}
- (void)movieEventFullscreenHandler:(NSNotification*)notification {
[player setFullscreen:NO animated:NO];
[player setControlStyle:MPMovieControlStyleEmbedded];
}
How can I dismiss that video screen by touching the Done button? Thanks guys.
You can use the notification of MPMoviePlayerPlaybackDidFinishNotification to observe the done button.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playObserver:)name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
and then,make a judge of quitting.
- (void) playObserver:(NSNotification *)notification
{
MPMoviePlayerController* player = moviePlayerView.moviePlayer;
if (player == [notification object]) {
if (_invalidVideoCount > MOVIE_TRY_TIMES) {
[self dismissViewController];
}
_invalidVideoCount++;
int reason = [[[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
//Whether continuous playback
if (![SINGLETON_CALL(SystemInfoManager) boolValueForKey:UserContinuousPlayEnableKey]) {
[self playFinishWithForce:YES];
return;
}
switch (reason) {
case MPMovieFinishReasonUserExited:
[self playFinishWithForce:YES];
break;
case MPMovieFinishReasonPlaybackError:
[self playFinishWithForce:YES];
break;
case MPMovieFinishReasonPlaybackEnded:
movieTryTimes = 0;
[self playFinishWithForce:NO];
break;
default:
break;
}
}
}
and the last.
- (void)playFinishWithForce:(BOOL)force
{
FileInfoItem *item = ARRAY_OBJECT_AT_INDEX(_playlist, _currentIndex);
BOOL quit = force || !item;
if (quit) {
[self dismissViewController];
} else {
[self playMovieWithItem:item];
}
}
Also you can use the notification of MPMoviePlayerPlaybackStateDidChangeNotification to make any observe.something detail see MPMoviePlayerController.h or https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MPMoviePlayerController_Class/Reference/Reference.html
I have found the problem. That's I laid [player stop] in the viewWillDisAppear so can't handle the notification. I fixed temporary by changing it to [player pause]. I appreciated any kind of your helps.
I have a view controller on which I have a table view, in table view each row have text field when i tap on the text field keyboard appear and hide the table view, and then can't see the editing, how can I fix this issue? I put observer that fix the alignment of view controller but it didn't work here is the code..
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
return YES;
}
-(void)keyboardWillShow {
// Animate the current view out of the way
[UIView animateWithDuration:0.3f animations:^ {
self.viewFrame = CGRectMake(0, -160, 320, 480);
}];
}
you have to write below code, it will hide and show keyboard.
====>.h file: declare one UITextField as below:
UITextField *actifText;
====>.m file:
-(void)viewDidAppear:(BOOL)animated
{
// Register notification when the keyboard will be show
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
// Register notification when the keyboard will be hide
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
-(void)viewDidDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void) keyboardWillShow:(NSNotification *)note
{
// Get the keyboard size
CGRect keyboardBounds;
[[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue: &keyboardBounds];
// Detect orientation
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect frame = self.tblName.frame;
// Start animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3f];
// Reduce size of the Table view
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
frame.size.height -= keyboardBounds.size.height;
else
frame.size.height -= keyboardBounds.size.width;
// Apply new size of table view
self.tblName.frame = frame;
// Scroll the table view to see the TextField just above the keyboard
if (self.actifText)
{
CGRect textFieldRect = [self.tblName convertRect:self.actifText.bounds fromView:self.actifText];
[self.tblName scrollRectToVisible:textFieldRect animated:NO];
}
[UIView commitAnimations];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
self.actifText = nil;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
self.actifText = textField;
}
-(void) keyboardWillHide:(NSNotification *)note
{
// Get the keyboard size
CGRect keyboardBounds;
[[note.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] getValue: &keyboardBounds];
// Detect orientation
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
CGRect frame = self.tblName.frame;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.3f];
// Reduce size of the Table view
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
frame.size.height += keyboardBounds.size.height;
else
frame.size.height += keyboardBounds.size.width;
// Apply new size of table view
self.tblName.frame = frame;
[UIView commitAnimations];
}
When you tap on some textfield inside cell, you must know current cell's indexpath, so when keyboard is shown, you can focus it.
-(BOOL) textFieldShouldBeginEditing:(UITextField *)textField
{
UITableViewCell *cell = (UITableViewCell *)[textField superview].superview;
NSIndexPath *idxPath = [table indexPathForCell:cell];
selectedIndex = idxPath.row;//instance variable
return YES;
}
-(void)keyboardWillShow {
[table scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
Also add following line to ViewDidLoad, keeping in mind to observe when keyboard have appeared. If you use UIKeyboardWillShowNotification, first keyboardWillShow will be called followed by textFieldShouldBeginEditing: which is wrong.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardDidShowNotification
object:nil];
and set
textfield.delegate = self;
in cellForRowAtIndexPath while creating textfield. It will call required methods.
When my app goes to background and back, modal view closes. Why is this happend? I tried with pause on and off. I have ARC enabled, if it is a useful info.
MPMoviePlayerViewController * player = [[MPMoviePlayerViewController alloc] initWithContentURL:targetURL];
[player.moviePlayer prepareToPlay];
[self presentMoviePlayerViewControllerAnimated:player];
In case anyone else stumbles across this (as I did before I found my own solution), I was able to prevent MPMoviePlayerViewController from exiting when the app backgrounds by subclassing it and removing it as an observer of UIApplicationDidEnterBackgroundNotification:
- (id)initWithContentURL:(NSURL *)contentURL {
self = [super initWithContentURL:contentURL];
if (self){
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}
return self;
}
You don't need to subclass MPMoviePlayerViewController - just do following after creating MPMoviePlayerViewController instance.
[[NSNotificationCenter defaultCenter] removeObserver:self.moviePlayerViewController name:UIApplicationDidEnterBackgroundNotification object:nil];
Here is full code that can help you
// Call this to start initialization and play movie
-(void)prepareMoviePlayer:(NSURL *)moviePath
{
moviePlayerViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:moviePath];
if ([[moviePlayerViewController moviePlayer] respondsToSelector:#selector(loadState)])
{
[[moviePlayerViewController moviePlayer] setControlStyle:MPMovieControlStyleNone];
[[moviePlayerViewController moviePlayer] setFullscreen:YES];
[[moviePlayerViewController moviePlayer] prepareToPlay];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerLoadStateDidChange:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
}
}
- (void) addPlayer
{
[[[moviePlayerViewController moviePlayer] view] setFrame:self.view.bounds];
[[self view] addSubview:[[moviePlayerViewController moviePlayer] view]];
}
static NSTimeInterval t;
// Call this on applicationWillResignActive
-(void) pauseMovieInBackGround
{
[[moviePlayerViewController moviePlayer] pause];
t = [[moviePlayerViewController moviePlayer] currentPlaybackTime];
[moviePlayerViewController.view removeFromSuperview];
}
// Call this on applicationWillEnterForeground
-(void) resumeMovieInFrontGround
{
[self addPlayer];
[[moviePlayerViewController moviePlayer] stop];
[[moviePlayerViewController moviePlayer] setInitialPlaybackTime:t];
[[moviePlayerViewController moviePlayer] play];
}
-(void)moviePlayerLoadStateDidChange:(NSNotification *)notification
{
if([[moviePlayerViewController moviePlayer] loadState] != MPMovieLoadStateUnknown)
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
[self addPlayer];
[[moviePlayerViewController moviePlayer] play];
}
}
-(void)videoPlayBackDidFinish:(NSNotification*)notification
{
[self dismissMoviePlayerViewControllerAnimated];
}
I am coming across this issue.
I've tried ChrisH's answer, but it didn't work for me until I put removeObserver into viewDidLoad() instead of init().
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}
Then it works. Enjoy it.