Add UITextField above keyboard iOS - ios

In my app I'm trying to add a UITextField on a accessoryView. It should work as follow:
I press on a UITextField in the user interface of app
The keyboard pop up and cover my UITextField on the user interface
To edit text I wanted to show a UITextField in an accessoryView just above the keyboard
I looked on the web but I found only stuff to add button on an accessoryView, I hope you can help me to find a solution to add an UITextField on an accessoryView.
Thank you
UPDATE
This is what I mean:
I hope you understand better my question, I'm not looking for a solution that should user scroll view or something, I don't want to change the interface of my app...

in .h
UIView *customtoolbar;
in .m At viewdidload add thi code
customtoolbar=[[UIView alloc]initWithFrame:CGRectMake(0, self.view.frame.size.height+50, 320, 50)];`
after this add this methods
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
[self pressdone];
return YES;
}
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
//216 is keyboard default height in portrait(162 in landscape)
[UIView animateWithDuration:0.7 animations:^{
[self addtoolbar:CGRectMake(0, self.view.frame.size.height-216-50, 320, 50)];
}];
return YES;
}
-(UIView *)addtoolbar:(CGRect )frame{
customtoolbar.frame=frame;
customtoolbar.backgroundColor=[UIColor darkGrayColor];
//give new frame to your textfield
txtfld.frame=CGRectMake(5,10, 220, 30);
[customtoolbar addSubview:txtfld];
UIButton *done=[UIButton buttonWithType:UIButtonTypeCustom];
done.frame=CGRectMake(235,10, 60, 30);
[done setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[done setTitle:#"Done" forState:UIControlStateNormal];
[done addTarget:self action:#selector(pressdone) forControlEvents:UIControlEventTouchUpInside];
[customtoolbar addSubview:done];
[self.view addSubview:customtoolbar];
return customtoolbar;
}
-(void)pressdone{
[self addtoolbar:CGRectMake(0, self.view.frame.size.height+50, 320, 50)];
//set there orignal frame of your textfield
txtfld.frame=CGRectMake(95, 170, 123, 37);
[self.view addSubview:txtfld];
[txtfld resignFirstResponder];
}

Add a view and then on top of it, please put a textfield and try. Below is the code.
UIView * container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
[container setBackgroundColor:[UIColor redColor]];
UITextField * newTextfield = [[UITextField alloc] initWithFrame:CGRectMake(50, 0, 100, 44)];
[newTextfield setBackgroundColor:[UIColor yellowColor]];
[container addSubview:newTextfield];
self.textField.inputAccessoryView = container;
This contains some colors, just to distinguish and identify the views. Change and format according to your needs. It will work. :)

you can use scroll view for this in your app & set content offset
- (void)textFieldDidBeginEditing:(UITextField *)textField {
self.scroll.contentOffset = CGPointMake(0, textField.frame.origin.y);
}
i hope this is relevent to your problem

This is what i have done in my apps
Add observers to UIKeyboardWillHideNotification & UIKeyboardWillShowNotification
When u review notification resize your view keyboardFrame
double duration = [[notification userInfo][UIKeyboardAnimationDurationUserInfoKey] doubleValue];
int curve = [[notification userInfo][UIKeyboardAnimationCurveUserInfoKey] intValue];
NSValue *value = [notification userInfo][UIKeyboardFrameEndUserInfoKey];
CGRect rawFrame = [value CGRectValue];
CGRect keyboardFrame = [self.view convertRect:rawFrame fromView:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
// Resize your View
[UIView commitAnimations]

Related

Disable font animation in UIButton [duplicate]

This question already has answers here:
How to stop unwanted UIButton animation on title change?
(24 answers)
Closed 4 months ago.
I am animating a view that is sliding down. In the view there is a simple UIButton. The view and the button have fixed widths and heights (I checked with adding a color as background). Although when use:
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
//Slide Down the notification
CGRect notificationsRect = self.notificationContainerView.bounds;
notificationsRect.origin.y = 0;
notificationViewController.view.frame = notificationsRect;
} completion:^(BOOL finished) {
[notificationViewController didMoveToParentViewController:self];
self.currentNotification = notificationViewController;
}];
then the view slides down perfectly, expect for that the text in the UIButton kind of fades in. It starts really small and animates to the correct font size.
How can I disable the animation of the text in the UIButton?
Is the effect you have something similar to what is below? I tried to imitate your situation by having a view with a UIButton inside with some some text set for the title of the button. I then animated the button similarly to the way you did. As you can see there isn't really a fade happening on the text of my button inside my view that is sliding so I wonder if there is something else at play for you. I have the code I used below also to mock the situation.
- (void)viewDidLoad {
[super viewDidLoad];
self.myView = [[UIView alloc] initWithFrame:CGRectMake(200, 0, 100, 100)];
self.myView.backgroundColor = [UIColor greenColor];
UIButton *myButton= [[UIButton alloc] initWithFrame:CGRectMake(10, 0, 80, 80)];
myButton.backgroundColor = [UIColor blueColor];
[myButton setTitle:#"fun times" forState:UIControlStateNormal];
[self.myView addSubview:myButton];
[self.view addSubview:self.myView];
UIButton *resetButton = [[UIButton alloc] initWithFrame:CGRectMake(300, 300, 50, 50)];
resetButton.backgroundColor = [UIColor blackColor];
[resetButton addTarget:self action:#selector(reset) forControlEvents:UIControlEventTouchUpInside];
UIButton *goButton = [[UIButton alloc] initWithFrame:CGRectMake(300, 100, 50, 50)];
goButton.backgroundColor = [UIColor redColor];
[goButton addTarget:self action:#selector(go) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:goButton];
[self.view addSubview:resetButton];
}
- (void)reset {
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
//Slide Up the notification
CGRect notificationsRect = self.myView.bounds;
notificationsRect.origin.y = 0;
notificationsRect.origin.x = 200;
self.myView.frame = notificationsRect;
} completion:nil];
}
- (void)go {
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
//Slide Down the notification
CGRect notificationsRect = self.myView.bounds;
notificationsRect.origin.y = 200;
notificationsRect.origin.x = 200;
self.myView.frame = notificationsRect;
} completion:nil];
}
Disable animations for UIButton using setAnimationsEnabled:(BOOL)enabled
Reference:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/index.html#//apple_ref/occ/clm/UIView/setAnimationsEnabled:

UITextField receives touch events even if I place a button on top

I am trying to block any touch event on UITTextField. To do so, I am trying to place a UIView/Button/Label on top of UITexfield.
But on simulator, I can still click at any location inside text field. What is wrong with my code? How can I put UIButton/Lable on top of textfield so that user can not click anywhere inside text field.
Please note I still want Number Keyboard input in the textfield. I just want to disable clicks/cut/copy/paste/select etc.
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 292, 50, 40)];
[self.textField becomeFirstResponder];
[self.textField setKeyboardType:UIKeyboardTypeNumberPad];
self.textField.delegate = self;
[self.view addSubview:self.textField];
UIButton *topViewonTextField = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight)];
topViewonTextField.backgroundColor = [UIColor clearColor];
[topViewonTextField setEnabled:NO];
//topViewonTextField.layer.zPosition = 100;
[self.view addSubview:topViewonTextField];
#define MAIN_SCREEN [UIScreen mainScreen]
#define ScreenWidth [MAIN_SCREEN bounds].size.width
#define ScreenHeight [MAIN_SCREEN bounds].size.height
If you want "block" a textField, tell to it:
texField.userInteractionEnabled = NO;
Big explanations:
// You create your textField, It can't receive events. By code or in Story
self.textField= [[UITextField alloc] initWithFrame:CGRectMake(10, 190, 80, 30)];
self.textField.placeholder = #"hola";
self.textField.userInteractionEnabled = NO;
self.textField.delegate = self;
[self.view addSubview:self.textField];
//Some Button or other event make the textField in editing mode.
UIButton *buttonToEdit = [[UIButton alloc] initWithFrame:CGRectMake(250, 250, 80, 80)];
[buttonToEdit setTitle:#"ActionToEdit" forState:UIControlStateNormal];
[buttonToEdit addTarget:self action:#selector(editMyTextField) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:buttonToEdit];
}
-(void)editMyTextField
{
self.textField.userInteractionEnabled = YES;
[self.textField becomeFirstResponder];
}
// The las step (to you) is in the delegate, when the editing finish, go back to no interaction
#pragma mark - TextFieldDelegate
-(void)textFieldDidEndEditing:(UITextField *)textField
{
if ([textField isEqual:self.textField]) {
self.textField.userInteractionEnabled = NO;
// more code here, validate...
}
}
Check this: How to disable paste option in menucontroller in iOS?

Changing frame of a UIView doesn't update its frame in its parent's subviews array. Hence the position doesn't changes

I am fairly new to IOS App Development. I have a view with 2 UIView and 1 ScrollView. One of the UIView is a footer which I want to be animated in such a way that it will hide/show to/from out of the screen based on some condition. However when I change the frame of the footer(show/hide footer), nothing happens.
So I did a NSLog of the footer and the self.view.subviews[2] and found that the frame of footer has changed successfully but the same change has not been reflected in the self.view.
If I do [self.view addSubview:footer] every time I call hideFooter/showFooter solves my problem but it messes up bad with my scroll view (which I cannot rectify, so this is not an option).
Am I missing something here? Is there a way to modify frame of a UIView such that the changes reflect in the UI too? (I have read most of the answers on modifying frame of a UIView. None seems to work without adding the UIView again to self.view).
Note that I have declared footer globally in the class just inside #implementation and have initialized it only once inside a method called from viewDidLoad.
#implementation PlayAudioViewController
UIButton *play;
UIButton *next;
UIButton *previous;
UIView* header;
UIView* footer;
- (void)viewDidLoad
{
[self addFooter];
}
-(void)addFooter{
footer = [[UIView alloc]initWithFrame:CGRectMake(0, self.view.frame.size.height * 1, self.view.frame.size.width, self.view.frame.size.height * 0.1)];
UIImageView *headerImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height * 0.1)];
headerImage.image = [UIImage imageNamed:#"Wooden-Background.jpg"];
[footer addSubview:headerImage];
footer.backgroundColor = [UIColor redColor];
queue = [[NSMutableArray alloc] init];
play = [[UIButton alloc]initWithFrame:CGRectMake(footer.frame.size.width * 0.475, footer.frame.size.height * 0.10, footer.frame.size.height * 0.80, footer.frame.size.height * 0.80)];
[play setBackgroundImage:[UIImage imageNamed:#"play_1.png"] forState:UIControlStateNormal];
[play setBackgroundImage:[UIImage imageNamed:#"stop.png"] forState:UIControlStateSelected];
[play addTarget:self action:#selector(universalplay:) forControlEvents: UIControlEventTouchUpInside];
play.enabled = YES;
[footer addSubview:play];
next = [[UIButton alloc]initWithFrame:CGRectMake(footer.frame.size.width * 0.675, footer.frame.size.height * 0.20, footer.frame.size.height * 0.60, footer.frame.size.height * 0.60)];
[next setBackgroundImage:[UIImage imageNamed:#"next.png"] forState:UIControlStateNormal];
[next addTarget:self action:#selector(nextplay:) forControlEvents: UIControlEventTouchUpInside];
next.enabled=NO;
[footer addSubview:next];
previous = [[UIButton alloc]initWithFrame:CGRectMake(footer.frame.size.width * 0.29, footer.frame.size.height * 0.20, footer.frame.size.height * 0.60, footer.frame.size.height * 0.60)];
[previous setBackgroundImage:[UIImage imageNamed:#"previous.png"] forState:UIControlStateNormal];
[previous addTarget:self action:#selector(previousplay:) forControlEvents: UIControlEventTouchUpInside];
previous.enabled=NO;
[footer addSubview:previous];
NSLog(#"%#", footer.subviews[1]);
[self.view addSubview:footer];
[self hideFooter];
}
-(void)showFooter{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2];
footer.frame = CGRectMake(0, self.view.frame.size.height * 0.9, self.view.frame.size.width, self.view.frame.size.height * 0.1);
//[self.view addSubview:footer];
[UIView commitAnimations];
NSLog(#"%#", self.view.subviews[0]);
NSLog(#"%#", self.view.subviews[1]);
NSLog(#"%#", ((UIButton *)((UIView *)self.view.subviews[2]).subviews[1]));
}
-(void)hideFooter{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2];
footer.frame = CGRectMake(0, self.view.frame.size.height * 1, self.view.frame.size.width, self.view.frame.size.height * 0.1);
//[self.view addSubview:footer];
[UIView commitAnimations];
}
As stated earlier, if I uncomment the commented statement in addFooter and showFooter, animation works perfectly but my scrollView gets screwed(newly added subviews stop getting reflected).
Also I am facing similar problem with play, pause and next button. These buttons will be enabled or disabled time to time. When I am changing their .enable property, the change is again not reflected in the self.view.
Please help me understand the reason behind this unusual behavior.

How to fit image in UITextView and Tap to get larger

I have created a Table-view in main ViewController once i touch the row it will take to the next view controller(DetailViewController) where it display the image and name of dish.And once i tap the image it should get larger but it is not getting bigger .The below code is which i have tried in DetailViewController.
DetailViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
imageView=[[UIImageView alloc] initWithFrame:CGRectMake(10, 10,100, 100)];
CGRect textViewFrame = CGRectMake(10, 10, 300, 400);
textView = [[UITextView alloc] initWithFrame:textViewFrame];
textView.returnKeyType = UIReturnKeyDone;
textView.backgroundColor=[UIColor whiteColor];
textView.editable=NO;
textView.delegate = self;
[self.view addSubview:textView];
[textView addSubview:imageView];
textView.alpha = 0.9;
textView.font = [UIFont systemFontOfSize:15];
if(mrowno==0)
{
imageView.image=[UIImage imageNamed:#"Dosa.jpg"];
textView.text = #"\n\n\n\n\n\n\n\nDOSA\nDosa, ";
imageButton = [[UIButton alloc]init];
[imageButton setFrame:CGRectMake(0, 0, 100, 100)];
[imageButton addTarget:self action:#selector(imageTapped:) forControlEvents:UIControlEventTouchUpInside];
[imageView addSubview:imageButton];
}
Here is the method to make image larger
-(void)imageTapped:(UIButton*)in_sender
{
[UIView transitionWithView:in_sender.superview duration:0.8f options:UIViewAnimationOptionCurveLinear animations:^
{
[in_sender.superview setFrame:CGRectMake(0, 0, 300, 500)];
}
completion:^(BOOL finished)
{
}];
}
You can increase and decrease the size of image by pinch in and pinch out,If it required
-(void)viewDidLoad
{
UIPinchGestureRecognizer* pinch=[[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinching:)];
[self.imageView addGestureRecognizer:pinch];
}
-(void)pinching:(UIGestureRecognizer*) recognizer
{
UIPinchGestureRecognizer* pinch=(UIPinchGestureRecognizer*) recognizer;
self.imageView.transform=CGAffineTransformScale(self.imageView.transform, pinch.scale, pinch.scale);
pinch.scale=1;
NSLog(#"pinching");
}
You do not want to use transitionWithView. Instead, you want to use + animateWithDuration: delay:options:animations:completion: (or any of its shorter variants...)
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
viewYouWantToAnimate.frame = CGRectMake(..., ..., ..., ...);
} completion:^{
//Add completion code here, or pass nil if you don't have anything to do.
}];
Edit: In case you were wondering what transitionWithView was used for... the AppleDocs have a great example of it adding animations for remove/addSubview methods (not frame modifications):
[UIView transitionWithView:containerView
duration:0.2
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
[fromView removeFromSuperview];
[containerView addSubview:toView];
} completion:NULL];

iOS - Closing a Subclassed UIView from view's uibutton

I have a custom subclassed uiview I created to display in-app notifications.
I can call the view just fine, but am having problems dismissing it using a uibutton (embedded in the custom view)
When the button is pressed, the app crashes and I get this error:
UPDATE - Fixed the above issue, but now only the button dismisses, and not the actual view. See updated code below.
-(id)initWithMessage:(NSString *)message{
self = [super initWithFrame:CGRectMake(0, -70, 320, 60)];
if (self) {
//Add Image
UIImage *image = [UIImage imageNamed:#"notice-drop-down"];
UIImageView *background = [[UIImageView alloc] initWithImage:image];
[self addSubview:background];
//Add Label
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, self.frame.size.height/2-25, 300, 50)];
[label setBackgroundColor:[UIColor clearColor]];
[label setTextColor:[UIColor blackColor]];
[label setText:message];
label.numberOfLines = 0;
[label setFont:[UIFont fontWithName:#"Hand of Sean" size:16]];
//NSLog(#"FONT FAMILIES\n%#",[UIFont familyNames]);
[self addSubview:label];
//Add Close Button
UIButton *closeButton = [[UIButton alloc] initWithFrame:CGRectMake(280, self.frame.size.height/2-15, 30, 30)];
UIImage *closeImage = [UIImage imageNamed:#"notice-close"];
[closeButton setImage:closeImage forState:UIControlStateNormal];
[closeButton addTarget:self action:#selector(closeNoticeDropDown:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:closeButton];
//Animate In
[UIView animateWithDuration:1
delay:0
options: UIViewAnimationCurveEaseIn
animations:^{
self.frame = CGRectMake(0,70,320,60);
}
completion:nil
];
}
return self;
}
-(void)closeNoticeDropDown:(id)self{
NoticeDropDown *notice = (NoticeDropDown *)self;
NSLog(#"Frame: %f",notice.frame.size.width);
//Animate In
[UIView animateWithDuration:1
delay:0
options: UIViewAnimationCurveEaseOut
animations:^{
notice.frame = CGRectMake(0,-70,320,60);
}
completion:^(BOOL finished){
[notice removeFromSuperview];
//notice = nil;
}
];
}
View call from another view controller:
noticeDropDown = [[NoticeDropDown alloc] initWithMessage:message];
[self.view insertSubview:noticeDropDown belowSubview:hudContainerTop];
You have declared your method to be a class method but are sending the message to an instance. If you want it to be a class method still, pass [NoticeDropDown class] as the target parameter to your addTarget:action:forControlEvemts: method. Otherwise replace the "+" with a "-" in the method declaration.
Also- when UIControl actions have sender parameters it will send the control as the sender - so you will get a UIButton instead of your view.
My recommendation is to change your action to an instance method and replace "sender" with "self".
I apologize for formatting I'm posting from my phone. I'll try to fix when back at a computer.
EDIT:
Change your updated method like so:
-(void)closeNoticeDropDown:(id)sender{
NSLog(#"Frame: %f",notice.frame.size.width);
//Animate In
[UIView animateWithDuration:1
delay:0
options: UIViewAnimationCurveEaseOut
animations:^{
self.frame = CGRectMake(0,-70,320,60);
}
completion:^(BOOL finished){
[self removeFromSuperview];
}
];
}
You don't need to pass self into a method, it always exists.
You probably try to call your method on your view instance (something like [noticeDropDown closeNoticeDropDown:...]) but closeNoticeDropDown: is a class method and you should call it this way:
[NoticeDropDown closeNoticeDropDown: noticeDropDown];
There's also few things in your animation code that look wrong:
[UIView commitAnimations]; calls should be removed as they are used in pair with [UIView beginAnimations:... context:...] method, they're not required with block-based animation
[sender removeFromSuperview]; call should go in animation's completion block, otherwise it will be called before your animation is even started and you won't get desired effect

Resources