iPhone: How to fix inputAccessoryView to View? - ios

I have a toolbar which I need to use when editing text, and when not.
In previous apps, I've moved the toolbar manually (listening for notifications, etc.)
But I want to use inputAccessoryView... so in my viewDidLoad, I do
for (/*myTextFields*/) {
textField.inputAccessoryView = keyboardToolbar;
}
[self.view addSubView:keyboardToolbar];
Which works fine, the toolbar appears, I click on a text field, toolbar slides up - all good.
But when I then hide the keyboard, inputAccessoryView drags my toolbar off the screen. Is there any way to tell the inputAcessoryView where it's fixed location is? - Or do I have to go back to my old way of listening for notifications etc...?

I solved this by listening for Notifications and moving the toolbar up... oh well.
Something like this does the job:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
/* Listen for keyboard */
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification
{
[keyboardToolbar setItems:itemSetFull animated:YES];
/* Move the toolbar to above the keyboard */
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect frame = self.keyboardToolbar.frame;
frame.origin.y = self.view.frame.size.height - 210.0;
self.keyboardToolbar.frame = frame;
[UIView commitAnimations];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
[keyboardToolbar setItems:itemSetSmall animated:YES];
/* Move the toolbar back to bottom of the screen */
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect frame = self.keyboardToolbar.frame;
frame.origin.y = self.view.frame.size.height - frame.size.height;
self.keyboardToolbar.frame = frame;
[UIView commitAnimations];
}
I guess input accessory view is literally just meant for something stuck on top of the keyboard :)

I've figured it out recently, and it seems few people have. So, I would like to direct you to this answer: https://stackoverflow.com/a/24855095/299711, which I will just copy below:
Assign your UIToolbar to a property in your view controller:
#property (strong, nonatomic) UIToolbar *inputAccessoryToolbar;
In your top view controller, add these methods:
- (BOOL)canBecomeFirstResponder{
return YES;
}
- (UIView *)inputAccessoryView{
return self.inputAccessoryToolbar;
}
And then (optionally, as it usually shouldn't be necessary), whenever the keyboard gets hidden, just call:
[self becomeFirstResponder];
That way, your inputAccessoryToolbar will be both your view controller's and your text view's input accessory view.

Related

Keyboard not hidden in ios

I have a UITextView (purpose : comment) pinned at the bottom of my screen, when the user wants to add a comment, the keyboard appears and I have the comment view shift upwards along with the comment. I also have a cancel button to hide the keyboard, but the keyboard isn't hidden
//Set up NSNotification for Keyboard
-(void) viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillToggle:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillToggle:)
name:UIKeyboardWillHideNotification object:nil];
}
//Code to shift comment view up with keyboard
- (void) keyboardWillToggle:(NSNotification *)aNotification
{
CGRect frame = [self.navigationController.toolbar frame];
CGRect keyboard = [[aNotification.userInfo valueForKey:#"UIKeyboardFrameEndUserInfoKey"] CGRectValue];
frame.origin.y = keyboard.origin.y - frame.size.height;
[UIView animateWithDuration:[[aNotification.userInfo valueForKey:#"UIKeyboardAnimationDurationUserInfoKey"] floatValue] animations:^
{
[self.navigationController.toolbar setFrame:frame];
}];
}
//Hide keyboard
-(void)cancelComment:(UIBarButtonItem*)sender{
NSLog(#"cancelComment called");
[self.view endEditing:YES];
}
I feel like this should work? "cancelComment called" is being logged to the console but the keyboard isn't hidden
SOLUTION:
You have forgotten to put:
[yourtextfield resignfirstresponder];
in your cancelComment function.
you can try
-(void)cancelComment:(UIBarButtonItem*)sender{
NSLog(#"cancelComment called”);
[self.navigationController.view endEditing:YES];
}
I think you textView not in self.view and in the self.navigationController.view
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[yourtextfieldname resignfirstresponder];
}
Hope this will you!

UITextField : Keyboard doesn't come up after first editing

I'm trying to move the my view up when keyboard appears and then down again on disappear.
The first time the keyboard appears , it works as intended . When I press 'Done' , keyboard disappears and view moves back. However , after this initial editing , clicking on the textfiled does nothing. The keyboard doesn't come up at all.
In viewDidLoad method I've written :
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
And implemented the following delegates :
- (void)keyboardDidShow:(NSNotification *)notification
{
//Assign new frame to your view
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
NSDictionary* info = [notification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[self.view setFrame:CGRectMake(0,-kbSize.height,320,460)];
[UIView commitAnimations];
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[self.view endEditing:YES];
return NO;
}
-(void)keyboardDidHide:(NSNotification *)notification
{ [UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
[self.view setFrame:CGRectMake(0,0,320,460)];
[UIView commitAnimations];
}
I don't recommend you to move self.view for it. Put all subviews on scrollview or tableview and assign this class on it.
https://github.com/michaeltyson/TPKeyboardAvoiding
You need to implement resignFirstResponder on your UITextfield so that the keyboard can be launched again. In your implementation what you could do is add the following line to your textFieldShouldReturn method:
[textfield resignFirstResponder];
If you change your -textFieldShouldReturn method to the following it should work.
-(BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
Per the documentation:
By returning NO, you could prevent the user from switching to another control
Returning NO, keeps focus on the control, so I'm assuming that the next time you tap the textFiled nothing happens because the system thinks that control is already focused.

Is there a way to disable transparency on the keyboard in iOS 7?

I would like to have a keyboard with a non-transparent keyboard - I couldn't get this with any of the supported UIKeyboardTypes. Is there another way around this?
I suppose I could just overlay a background view under the keyboard with the color I want - would there be a good way to animate that background view in sync with the keyboard show animation?
The keyboard in iOS7 is translucent when app is compiled in Xcode 5 with a Base SDK of iOS 7.
If you build the app on Xcode 4.6.x instead, you'll have the non-translucent keyboard as before.
(i know this is a shitty fix but nonetheless, i thought i'd suggest it)
anyways, you could alternatively try making use of the default keyboard notifications:
UIKeyboardWillShowNotification
UIKeyboardWillHideNotification
should go something like:
-(void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
-(void)viewWillDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
-(void)keyboardWillShow:(NSNotification *)note
{
/*
Would have used:
CGRect rectStart = [note.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGRect rectEnd = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
Reason for not using:
The above two keys are not being used although, ideally, they should have been
since they seem to be buggy when app is in landscape mode
Resolution:
Using the deprecated UIKeyboardBoundsUserInfoKey since it works more efficiently
*/
CGRect rectStart_PROPER = [note.userInfo[UIKeyboardBoundsUserInfoKey] CGRectValue];
rectStart_PROPER.origin.y = self.view.frame.size.height;
UIView *vwUnderlay = [self.view viewWithTag:8080];
if (vwUnderlay) {
[vwUnderlay removeFromSuperview];
}
vwUnderlay = [[UIView alloc] init];
[vwUnderlay setFrame:rectStart_PROPER];
[vwUnderlay setBackgroundColor:[UIColor orangeColor]];
[vwUnderlay setTag:8080];
[self.view addSubview:vwUnderlay];
[UIView animateWithDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]
delay:0
options:[note.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16
animations:^{
[vwUnderlay setFrame:CGRectOffset(vwUnderlay.frame, 0, -vwUnderlay.frame.size.height)];
}
completion:nil];
}
-(void)keyboardWillHide:(NSNotification *)note
{
UIView *vwUnderlay = [self.view viewWithTag:8080];
[UIView animateWithDuration:[note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]
delay:0
options:[note.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16
animations:^{
[vwUnderlay setFrame:CGRectOffset(vwUnderlay.frame, 0, vwUnderlay.frame.size.height)];
}
completion:^(BOOL finished){
[vwUnderlay removeFromSuperview];
}];
}
Apple does not allow anyone to modify the default keyboard. If you are going to be using iOS 7 then you will have to deal with the translucent keyboard.
The only other way I can think of is designing your own keyboard, but that's a tedious process to go through.
I was looking into the same thing today, and I found a simple workaround (although, not yet sure how reliable it is).
In order to work, I've set up an inputAccessoryView for my keyboard controls (UITextView and UITextField). In the UIView class that I've set as the inputAccessoryView I added the followings:
-(void)layoutSubviews{
[super layoutSubviews];
frame = _lKeyboardBackground.frame;
frame.origin.y = [self convertPoint:self.frame.origin toView:self.superview].y+self.frame.size.height;
frame.size.width = self.bounds.size.width;
frame.origin.x = 0;
frame.size.height = 500;
_lKeyboardBackground.frame = frame;
[self refreshKeyboardBackground];
}
-(void)didMoveToSuperview{
[super didMoveToSuperview];
if (self.superview) {
[self.superview.layer insertSublayer:_lKeyboardBackground atIndex:lMagicLayerIndex];
}
else {
[_lKeyboardBackground removeFromSuperlayer];
}
}
-(void)setFrame:(CGRect)frame{
[super setFrame:frame];
[self refreshKeyboardBackground]; // setFrame: is called when keyboard changes (e.g: to a custom input view)
}
-(void)refreshKeyboardBackground{
if (_lKeyboardBackground.superlayer) {
CALayer *parent = _lKeyboardBackground.superlayer;
[_lKeyboardBackground removeFromSuperlayer];
[parent insertSublayer:_lKeyboardBackground atIndex:lMagicLayerIndex];
}
}
_lKeyboardBackground is a CALayer that I've setup in the init methods:
_lKeyboardBackground = [CALayer layer];
_lKeyboardBackground.backgroundColor = [[UIColor redColor] CGColor]; //or some less annoying color
This should theoretically pass Apple's approval, but I never tested. There's also plenty of changes this will not work in future versions, or in some other situations (e.g when there's a split keyboard on the iPad)
lMagicLayerIndex that I use is 1, which gives the absolute color.
Note that the blur can still be noticed on key-strokes.
Use keyboard notification to show/hide a custom black view behind the keyboard (or white if you use the white keyboard) and voila, transparent no more.

View not moving up when keyboard appears [duplicate]

This question already has answers here:
How can I make a UITextField move up when the keyboard is present - on starting to edit?
(98 answers)
Closed 9 years ago.
i have a UI textfield in a subview.I am adding it to a view .When the keyboard pops-up ,i want to animate the view to which i am adding this subview.I have written all my textfield delegate functions in my subview class only.So if i use Animate textfield function it doesn't move the parent view instead thy subview is animated....please help me
Try this:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
in the viewDidLoad
and then this
- (void)keyboardWillHide:(NSNotification *)aNotification
{
// the keyboard is hiding reset the table's height
NSTimeInterval animationDuration =
[[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = self.view.frame;
frame.origin.y += 160;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
}
- (void)keyboardWillShow:(NSNotification *)aNotification
{
// the keyboard is showing so resize the table's height
NSTimeInterval animationDuration =
[[[aNotification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = self.view.frame;
frame.origin.y -= 160;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.view.frame = frame;
[UIView commitAnimations];
}
in your view controller
Most likely you will have to change the value (160) that I put here based on your specific view
have you tried textFieldDidBeginEditing i don know whether you tried this or not and whether it is proper way or not. I used this it is working less lines to achieve
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
self.view.frame=CGRectMake(0, -300, 320, 700);
}
this will move your root view to top so your sub view automatically will move to top text field will not be hide behind keyboard and sorry i don have reputation to comment

Shifting the view for the keyboard and then pressing home, back to view results in non shifted view?

I use the code below atm. It is working fine as long as you don't quit the app (press home) while the keyboard is up. So I thought, simple, just resignFirstResponder in viewWillDissappear:(BOOL)animated, but that does not get called pressing home apparently...
So quick recap of the problem scenario:
Tap the textView -> keyboard comes up, view is shifted
Press home
Open app again -> keyboard still up, view is back where it was, so content not visible
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void) keyboardWillShow: (NSNotification*) aNotification;
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = [[self view] frame];
rect.origin.y -= 60;
[[self view] setFrame: rect];
[UIView commitAnimations];
}
- (void) keyboardWillHide: (NSNotification*) aNotification;
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = [[self view] frame];
rect.origin.y += 60;
[[self view] setFrame: rect];
[UIView commitAnimations];
}
You could add notification for enter background event, like the following code
- (void)viewDidLoad
{
//Add this
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(handleEnteredBackground:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
}
And in the function
- (void) handleEnteredBackground:(NSObject*)obj
{
//Adjust your views
}

Resources