I have placed out a UIView with a UIButton as a subview in a ViewController in Interface Builder. I also have a UITextField where I have a action witch is triggered every time I type something in it. When I type something my view is supposed to get higher and the button should move to the bottom of the view. But when I type the first letter in the textfield the view resizes but the button doesn't move. When I type a second letter the button moves. Probably because the view is already resized. My question is how to get this to work simultaneously when typing the first letter in the textfield.
My code:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyPressed:) name:UITextFieldTextDidChangeNotification object:textField];
- (void)keyPressed:(NSNotification*)notification{
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 200.0);
button.frame = CGRectMake(button.frame.origin.x, (view.frame.size.height-button.frame.size.height), button.frame.size.width, button.frame.size.height);
}
try to implement this method:
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
// put your action here
}
Solved it by putting the button at the bottom of the view. Then when I resized the view the button followed along by staying at the bottom. I didn't need to programmatically move the button.
Related
This is Screenshot
In View B, When keyboard is shown and pop viewController to View A with interactivePopGestureRecognizer, the keyboard is still stay here :(
How can let keyboard move with view B ?
(like iMessage or Facebook Messenger)
ps: I'm try to get keyboard view and add to self.view, it's useful, but i think it's not a good way.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShown)
name:UIKeyboardDidShowNotification object:nil];
and
- (void)keyboardDidShown
{
UIView * keyboardView = self.textView.inputAccessoryView.superview;
[self.view addSubview: keyboardView];
}
Try this solution:
https://github.com/cotap/TAPKeyboardPop
This is lightweight category that listens interactivePopGestureRecognizer gesture and animating keyboard accordingly.
You don't add keybordView to the view. If you want to show keyboard for your UITextField/UITextView you call becomeFirstResponder on that object. In your example it should be:
[self.textView becomeFirstResponder];
If you want to hide keyboard you call:
[self.textView resignFirstResponder];
And if you want to hide your keyboard before you dismiss your ViewA you should call it in the beginning of your interactivePopGestureRecognizer when you start animation to show ViewB.
Hope it help.
//EXTENDED
I don't know why you are trying to add accessoryView as a subview to your view
- (void)keyboardDidShown
{
UIView * keyboardView = self.textView.inputAccessoryView.superview;
[self.view addSubview: keyboardView];
}
And I don't understand why do you use notification centre.
The functionality that the keyboard stay when you dismissed the view (as iMessage app) is a standard functionality.
Just use
[self.textView becomeFirstResponder];
when you want to show the keyboard and don't call
[self.textView resignFirstResponder];
when you pop your view controller. iOS does the job for you.
I have created two uiviewcontrollers in storyboard. I am adding second UIview as a subview to 1st view when a button is pressed.
Now, my subview has a done and cancel button, which upon been touched, the subview has to be removed from the main view and needs to send some data back to main view. Is using delegates the only way to solve this? Please explain if there is any other simpler or better option.
Thank you :)
It sounds like the question is just about subviews of the 1st view controller's view. In that case, the 1st view controller can directly inspect all of them. i.e. Say the data that you'd like "passed" between views is the text of a UITextField contained on the subview.
You have an outlet to the subview, probably painted in IB?
// MyViewController.m
#property(weak, nonatomic) IBOutlet UIView *subview; // self.view is it's parent
Create an outlet that connects to whatever subviews you want data from:
#property(weak, nonatomic) IBOutlet UITextField *textField; // probably, subview is it's parent
Hide and show the "dialog":
self.subview.alpha = 0.0; // to hide (alpha is better than 'hidden' because it's animatable
self.subview.alpha = 1.0; // to show
When the button is pressed:
- (IBAction)pressedDoneButton:(id)sender {
self.subview.alpha = 0.0;
// or, prettier:
[UIView animateWithDuration:0.3 animations:^{ self.subview.alpha = 0.0; }];
// the text field still exists, it's just invisible because it's parent is invisible
NSLog(#"user pressed done and the text that she entered is %#", self.textField.text);
}
The point is that data is not being passed between views. The view controller has pointers to views. Some, like buttons generate events for the view controller to react to. Others carry data that the view controller can see.
I have a UITextField in my iOS app. When a user enters text and clicks Return, the keyboard goes away due to a call to an IBAction with "resignFirstResponder."
However, XCode does not let me drag a line from the UIView itself to File Owner. How do I associate touching the background of a UIView with an IBAction that makes the keyboard go away?
You can use UITapGestureRecognizer. see: Dismiss keyboard by touching background of UITableView
so instead of tableview, just add it to your view instead:
UITapGestureRecognizer *gestureRecognizer = [[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)] autorelease];
gestureRecognizer.cancelsTouchesInView = NO; //so that action such as clear text field button can be pressed
[self.view addGestureRecognizer:gestureRecognizer];
and have a method to hide your keyboard
- (void) hideKeyboard {
[self.view endEditing:YES];
}
You've already noticed that you can't drag from the UIView to the file's owner to assoctiate an action with a touch.
The way to work around this is to change the class of the background view from UIView to UIControl and hook up an action from there to a method in your controller to stop editing.
That's because a UIControl can respond to touch events, and a UIView does not, but a UIControl subclasses UIView, and so it can be used in place of a UIView.
I wrote an example project a while ago that uses this technique. Have a look at the secondViewController's xib file and see how I've change the class of the background view and hooked it up to a an action in the controller to dismiss the keyboard.
Use the touchesBegan with Event and end editing on the view:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
One easy way to do it is to create a big transparent UIButton behind the view.
I have a UIButton in UIViewController, i want add to dynamic number of UITextViews in the ViewController on this button click action. After creating textviews i am moving it using touches, but as i create a new textview the previous textview does not respond to touch event.Why is this happening?
here is my code:
-(IBAction)createTextView{
UITextView *textView =[[UITextView alloc]init];
textView.frame=CGRectMake(40,40,10,300);
[self.view addSubview:textView];
}
Use textView.delegate=self; after allocating the textView. Hope it will work fine once its done.
When an UITextField is firstResponder, I would like to bring to front an UIDatePicker (bottom part of the screen) without the "going down keyboard" (no call to UITextField resignFirstResponder).
The aim is to process like UIKeyboard of UITextField which pop-up on nearly everything when it becomeFirstResponder. modalViewController seems to be fullscreen only.
- showDatePicker:(id)sender {
if([taskName isFirstResponder]) [taskName resignFirstResponder];
[self.view.window addSubview: self.pickerView];
// size up the picker view and compute the start/end frame origin
(...)
[UIView commitAnimations];
}
This example is an animation of keyboard going down, and DatePicker going up, behind and not in front.
Do you know a solution ? A piece of code would be welcome. Thanks in advance.
This is simply done by setting the input view of the text field to the Picker View. Then, on Editing did begin tell the picker view to becomeFirst responder. Like this
textField.inputView = pickerView
then using an IBAction called when the Editing Did Begin
-(IBAction) setPickerViewAsFirstResponder:(id)sender
{
[pickerView becomeFirstResponder];
}
This works perfectly. You'll need to implement code to actually set what the picker view is currently showing to be a string in the text field still.
This definitely can be done... simply implement the method below after setting UIViewController <UITextFieldDelegate> in your .h
Long story short, this overrides the keyboard loading before text editing begins.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
// Make a new view, or do what you want here
UIDatePicker *pv = [[UIDatePicker alloc] initWithFrame:CGRectMake(0,245,0,0)];
[self.view addSubview:pv];
return NO;
}