I am stuck in very simple functionality in iOS.
I am trying to send the data from a textField which is inside the subview of a scroll view. Button is firing the action when I hit the button, when keyboard is closed as soon as I try to write something and keyboard opened button stop responding.
VideoViewController:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
controller.videoID = videoID;
controller.channelID = channelID;
controller.view.frame = self.commentView.bounds;
[self.commentView addSubview:controller.view];
// [self.scrollView addSubview:controller.sendBtn];
[self addChildViewController:controller];
[controller didMoveToParentViewController:self];
}
CommentViewController:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
controller.videoID = videoID;
controller.channelID = channelID;
controller.view.frame = self.commentView.bounds;
[self.commentView addSubview:controller.view];
// [self.scrollView addSubview:controller.sendBtn];
[self addChildViewController:controller];
[controller didMoveToParentViewController:self];
}
-(void)keyboardWillShow:(NSNotification *)notification
{
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.3 animations:^{
CGRect f = self.view.frame;
f.origin.y = -keyboardSize.height+100;
self.sendView.frame = f;
}];
_sendBtn.userInteractionEnabled = YES;
}
-(void)keyboardWillHide:(NSNotification *)notification
{
[UIView animateWithDuration:0.3 animations:^{
CGRect f = self.view.frame;
f.origin.y = 0.0f;
self.sendView.frame = f;
}];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[commentTextField resignFirstResponder];
return YES;
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
return ![view isKindOfClass:[UIButton class]];
}
Please suggest something on this.
Thank you.
I faced this problem, too
It took me 2 days to find the solution. You need to set the cancel touches flag to false for ScrollVIew/View.
Actually, scrollview touch is enable and it is not allowing the button to interact.
This is the only reason send button is not working.
Related
I am building a social network App and I need a commenting page like the on in Instagram or any other App, I have tried the following:
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:_postsTableView];
NSIndexPath *indexPath = [_postsTableView indexPathForRowAtPoint:buttonPosition];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LikesViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"LikesViewController"];
controller.postid = postid[indexPath.row];
[self presentViewController:controller animated:NO completion:nil];
but I need a UITableView with a footer that has a UITextField, the page should display the previous comments and have the option to let the user add new comments, can anyone point me in the right direction? Thanks in advance.
#ViewDidLoad
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapReceived:)];
[tapGestureRecognizer setDelegate:self];
[self.view addGestureRecognizer:tapGestureRecognizer];
Dismiss keyboard & end editing when tapped outside
-(void)tapReceived:(UITapGestureRecognizer *)tapGestureRecognizer
{
[self.view endEditing:YES];
}
Keyboard methods
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
[self.view endEditing:YES];
return YES;
}
- (void)keyboardDidShow:(NSNotification *)notification
{
// Assign new frame to your view
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.1 animations:^{
CGRect f = self.view.frame;
f.origin.y = -keyboardSize.height + 180;
self.view.frame = f;
}];
}
-(void)keyboardDidHide:(NSNotification *)notification
{
[UIView animateWithDuration:0.1 animations:^{
CGRect f = self.view.frame;
f.origin.y = 0.0f;
self.view.frame = f;
}];
}
Feel free to adjust the animation duration as you see fit.Good luck
I am currently writing an iOS app and encountered some animation issue. The following is the test code to show my question. It's just a very simple animation that lets the textField to move up when the keyboard shows and move down when the keyboard hides. Interestingly, if it is an English keyboard, it seems that the UIView animation somehow conflicts with the keyboard animation and no animations are performed, but if I switch to the Chinese keyboard, it works fine. I just want to confirm that whether it is a bug from apple....
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UITextField *textField = [[UITextField alloc] init];
self.textField = textField;
textField.placeholder = #"Click me!!";
textField.frame = CGRectMake(100, 350, 150, 40);
[self.view addSubview:self.textField];
self.textField.delegate = self;
}
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
[UIView animateWithDuration:0.25 animations:^{
CGRect frame = self.textField.frame;
frame.origin.y -= 100;
self.textField.frame = frame;
}];
return YES;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[self.textField resignFirstResponder];
[UIView animateWithDuration:0.25 animations:^{
CGRect frame = self.textField.frame;
frame.origin.y += 100;
self.textField.frame = frame;
}];
return YES;
}
UPDATE
It seems that it is a bug from apple... I tried to use iOS 8.3 simulator, and it works super smoothly... In iOS 9.3, if you just try showing and hiding the keyboard, even without moving the textField, the animation will get stuck after several operations...
I'd advise you to move the animation blocks to methods from the notification UIKeyboardWill{Show|Hide}Notification. The delegate methods from your text field are asking about the text field and its behavior – nothing to do with the keyboard itself (and you can even synchronize the duration, curve and delay).
You're returning YES to -textFieldShouldReturn: which is only supposed to check if the text field should process the return key tap.
From my experience with animations, sometimes everything works fine when testing with a real device. I made the suggested changes over here and everything worked fine on an iPhone 5c (iOS 8.1) and iPhone 6s Plus (iOS 10, Beta 1).
Here's a snippet of how it looks like:
- (void)viewDidLoad {
[super viewDidLoad];
[self setupNotifications];
[self initUIElements];
}
- (void)initUIElements {
CGRect frame = CGRectMake(0.f, 20.f, 200.f, 44.f);
self.textField = [[UITextField alloc] initWithFrame:frame];
self.textField.center = CGPointMake(self.view.center.x, 32.f);
self.textField.placeholder = #"Placeholder";
self.textField.delegate = self;
[self.view addSubview:self.textField];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50.f, 50.f)];
self.imageView.center = self.view.center;
self.imageView.backgroundColor = [UIColor magentaColor];
[self.view addSubview:self.imageView];
}
- (void)setupNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)keyboardWillHide:(id)sender {
[UIView animateWithDuration:1.f animations:^{
self.textField.center = CGPointMake(self.view.center.x, 32.f);
self.imageView.center = self.view.center;
}];
}
- (void)keyboardWillShow:(id)sender {
[UIView animateWithDuration:1.f animations:^{
self.textField.center = CGPointMake(self.view.center.x, 62.f);
self.imageView.center = CGPointMake(self.view.center.x, (self.view.center.y - 50.f));
}];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
#lin fu
.m
- (void)viewDidLoad {
[super viewDidLoad];
UITextField *textField = [[UITextField alloc] init];
textField.placeholder = #"Click me!!";
textField.delegate = self;
textField.frame = CGRectMake(100, 350, 150, 40);
[self.view addSubview:textField];
}
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
[UIView animateWithDuration:0.25 animations:^{
CGRect frame = textField.frame;
frame.origin.y -= 100;
textField.frame = frame;
}];
return YES;
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
[UIView animateWithDuration:0.25 animations:^{
CGRect frame = textField.frame;
frame.origin.y += 100;
textField.frame = frame;
}];
return YES;
}
in .h
Try this out. It works for me.
you have another option you can use the third party library call TPAvoidingKeyBoard it will help you out in there
I'm trying to flip animate a view into another view, which corresponds of a small section of the screen. Both views have the same dimensions and center.
I keep getting as a result the animation of the full screen. From the code below, can somebody please let me know what the heck i'm doing wrong?
Thank you,
-j
+ (void) flipView:(UIView*)viewA toView:(UIView*)viewB wait:(Boolean)wait
{
// get parent view
UIView *parent = [viewA superview];
CGRect r = viewA.frame;
// create container view with the same dimensions as ViewA
UIView *containerView = [[UIView alloc] initWithFrame:viewA.bounds];
containerView.center = viewA.center;
// attache both views to intermidiate view
[containerView addSubview:viewA];
[containerView addSubview:viewB];
[viewA removeFromSuperview];
[parent addSubview:containerView];
viewB.alpha = 0;
viewA.alpha = 1;
// Perform the annimation
__block BOOL done = NO;
[UIView transitionWithView:viewA
duration:2.0
options: (UIViewAnimationOptionTransitionFlipFromTop)
animations:^{
viewA.alpha = 0;
viewB.alpha = 1; }
completion:^(BOOL finished) {
done = YES;
// detach all views
[viewA removeFromSuperview];
[viewB removeFromSuperview];
[containerView removeFromSuperview];
}
];
if(wait) {
while (done == NO)
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
First get rid of the old animation code (or at least commit it), it should look like this:
+ (void) flipView:(UIView*)viewA toView:(UIView*)viewB wait:(BOOL)wait
{
viewB.alpha = 0;
viewA.alpha = 1;
__block BOOL done = NO;
[UIView transitionWithView:viewA
duration:2.0
options: (UIViewAnimationOptionTransitionFlipFromTop)
animations:^{
viewA.alpha = 0;
viewB.alpha = 1; }
completion:^(BOOL finished) {
done = YES;
}
];
if(wait) {
while (!done)
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
}
Second, the superview of the subview that you want to transition is actually going to get the transition. So this means that you'll have to add viewA and viewB to a subview, add this subview to another view and then do the animation.
Here is a solution without any hacks with runloop. Just use the first message to run a transition to another view, and the second message to return to original state:
- (void) forwardTransitionFromView: (UIView *) viewA toView: (UIView *) viewB
{
NSAssert(viewA.superview, #"The 'from' view should be added to a view hierarchy before transition");
NSAssert(!viewB.superview, #"The 'to' view should NOT be added to a view hierarchy before transition");
CGSize viewASize = viewA.bounds.size;
viewB.frame = CGRectMake(0.0, 0.0, viewASize.width, viewASize.height);
[UIView transitionWithView:viewA
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[viewA addSubview:viewB];
}
completion:NULL];
}
- (void) backwardTransitionFromView: (UIView *) viewB toView: (UIView *) viewA
{
NSAssert([viewB.superview isEqual:viewA], #"The 'from' view should be a subview of 'to' view");
[UIView transitionWithView:viewA
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[viewB removeFromSuperview];
}
completion:NULL];
}
Why dont you flip both views in same direction?
-(void) FlipView:(bool) fromRight {
if(fromRight) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:view1 cache:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:view2 cache:YES];
[UIView commitAnimations];
}
else {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDelegate:self];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view1 cache:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:view2 cache:YES];
[UIView commitAnimations];
}
}
and call the method like below:
[view1 setHidden:NO];
[self FlipView:YES];
[view2 setHidden:YES];
to reverse the animation:
[view2 setHidden:NO];
[self FlipView:NO];
[view1 setHidden:YES];
I am getting problem when trying to move my scroll view up when the keyboard appears.
The scroll view moves up in ios7 but in ios6 it doesn't and there is additional white space above the keyboard that hides the controls on the screen
my code:
- (void)viewWillAppear:(BOOL)animated
{
[super viewDidAppear:animated];
keyboardIsShown = NO;
[super viewWillAppear:animated];
[[self view] endEditing:YES];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:self.view.window];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:self.view.window];
}
- (void)keyboardWillShow:(NSNotification *)n
{
if (keyboardIsShown) {
return;
}
NSDictionary* userInfo = [n userInfo];
// get the size of the keyboard
CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// resize the noteView
CGRect viewFrame = self.scrollView.frame;
viewFrame.size.height -= (keyboardSize.height - kTabBarHeight);
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
// The kKeyboardAnimationDuration I am using is 0.3
[UIView setAnimationDuration:kKeyboardAnimationDuration];
[self.scrollView setFrame:viewFrame];
[UIView commitAnimations];
scrollView.contentSize = formView.frame.size;
keyboardIsShown = YES;
}
Whats the problem here. pls help
The problem is, that you only change size of the scroll view, but you don't tell the scrollview to scroll to the text field.
Look at my method scrollToEditingTextField for better understanding.
- (void)keyboardWillShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize beginSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// keyboard will appear
if(!_keyboardShowed) {
_keyboardShowed = YES;
[UIView animateWithDuration:0.4
animations:^{
CGFloat scrollHeight =_scrollView.size.height - (IS_PORTRAIT_ORIENTATION ? beginSize.height : beginSize.width);
CGRect scrollFrame = _scrollView.frame;
scrollFrame.size.height = scrollHeight;
_scrollView.frame = scrollFrame;
}
completion:^(BOOL finished){ }];
}
[self scrollToEditingTextField];
}
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize endSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
// keyboard will disappear
if(_keyboardShowed) {
CGFloat scrollHeight =_scrollView.size.height + (IS_PORTRAIT_ORIENTATION ? endSize.height : endSize.width);
CGRect scrollFrame = _scrollView.frame;
scrollFrame.size.height = scrollHeight;
_scrollView.frame = scrollFrame;
_keyboardShowed = NO;
}
}
-(void)scrollToEditingTextField {
// find which text field is currently editing
UITextField *editingTextFiled = [self editingTextField:self.thisView];
if(editingTextFiled == nil) return; // text field didnt found
CGPoint scrollPoint = [editingTextFiled convertPoint:CGPointMake(0, 0) toView:self.scrollView];
scrollPoint.y -= 70;
scrollPoint.x = 0;
[_scrollView setContentOffset:scrollPoint animated:YES];
}
-(UITextField*)editingTextField:(UIView*)view
{
if( ( [[view class] isSubclassOfClass:[UITextField class]] ||
[[view class] isSubclassOfClass:[UITextView class]] ) &&
[view isFirstResponder] ) {
return (UITextField*)view;
}
for(UIView *subview in view.subviews ) {
if([[subview class] isSubclassOfClass:[UISearchBar class]]) {
return nil;
}
if( ( [[subview class] isSubclassOfClass:[UITextField class]] ||
[[subview class] isSubclassOfClass:[UITextView class]] ) &&
[subview isFirstResponder] ) {
return (UITextField*)subview;
}
}
// recursion
for(UIView *subview in view.subviews ) {
UITextField *textField = [self editingTextField:subview];
if(textField) return textField;
}
return nil;
}
I'm new to iOS, i want to update the text in ViewDidLoad() function.
This is my button function, When button is clicked animation take place and also adds the value "1" to "resultText.text"
- (IBAction)oneButton1:(id)sender {
oneBtn2.userInteractionEnabled = YES;
CGRect frame = oneBtn1.frame;
CGRect frame1 = reffButton.frame;
frame.origin.x = frame1.origin.x;
frame.origin.y = frame1.origin.y;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: 3.0];
[UIView animateWithDuration:3.0 animations:^{
[oneBtn1 setTransform:CGAffineTransformMakeScale(.4, .4)];
} completion:^(BOOL finished) {
oneBtn1.hidden = YES;
price = [resultText.text intValue];
[resultText setText:[NSString stringWithFormat:#"%i", price+1]];
}];
oneBtn1.frame = frame;
[UIView commitAnimations];
}
Problem: The above text value is 1 but in ViewDidLoad is 0 ,
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"%#", resultText.text); // output is 0 instead of 1;
}
Please anyone tell me how to update the text value in ViewDidLoad function ...
ViewDidLoad calling only once when the object is creating .So you can't update the thing in ViewDidLoad.ViewDidLoad use for initialising the parameters and set the initial settings when an object creating.
This is because every time your view will load it create new object of your textField, thats why you are unable to fetch previous (because its new textField not old one).So you have to save your text some where, for example you can use NSUserDefaults
SetText
NSString *result=[NSString stringWithFormat:#"%i", price+1];
[resultText setText:];
//Also set it to NSUserDefaluts
[[NSUserDefaults standardUserDefaults] setValue:result forKey:#"key"];
[[NSUserDefaults standardUserDefaults] synchronize];
Get Text
- (void)viewDidLoad
{
[resultText setText:[[NSUserDefaults standardUserDefaults] valueForKey:#"key"]];
NSLog(#"%#", resultText.text);
}
EDIT
You can make animation afterButton click, so call this method in button click event
-(void)animateImage
{
if ([resultText.text isEqualToString:#"3"]) {
//make your animation
}
}
You can use a method to do that
- (void)updateLabel {
oneBtn2.userInteractionEnabled = YES;
CGRect frame = oneBtn1.frame;
CGRect frame1 = reffButton.frame;
frame.origin.x = frame1.origin.x;
frame.origin.y = frame1.origin.y;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: 3.0];
[UIView animateWithDuration:3.0 animations:^{
[oneBtn1 setTransform:CGAffineTransformMakeScale(.4, .4)];
} completion:^(BOOL finished) {
oneBtn1.hidden = YES;
price = [resultText.text intValue];
[resultText setText:[NSString stringWithFormat:#"%i", price+1]];
}];
oneBtn1.frame = frame;
[UIView commitAnimations];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self updateLabel];
NSLog(#"%#", resultText.text); // output is 0 instead of 1;
}