I'm trying to create a search bar similar to the one in safari browser on iPad. I think its a UITextview only.
On click of the control, its size will expand. And when orientation is rotated, it maintains the size accordingly.
How can I achieve that using auto-resizing option? Or do I've to code manually to achieve it?
You can do all this directly in Interface Builder.
The Search Bar component gives you the appropriate functionality. To make the bar resize properly, you just need to anchor it to the appropriate sides of the screen and make it stretchable. Try opening this file with IB for an example.
Use the below code to your controller and make sure the you have a textfield delegate.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
UIInterfaceOrientation orientation = self.interfaceOrientation;
if (orientation== UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
if(textField==searchField){
CGRect searchFrame = searchField.frame;
searchFrame.size.width += 150;
searchFrame.origin.x -= 150;
[UIView beginAnimations: #"GrowTextField" context: nil];
{
searchField.frame = searchFrame;
[UIView setAnimationDuration: 0.5];
}
[UIView commitAnimations];
}
}
else if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
if(textField==searchField){
CGRect searchFrame = searchField.frame;
searchFrame.size.width += 150;
searchFrame.origin.x -= 150;
[UIView beginAnimations: #"GrowTextField" context: nil];
{
searchField.frame = searchFrame;
[UIView setAnimationDuration: 0.5];
}
[UIView commitAnimations];
}
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
UIInterfaceOrientation orientation = self.interfaceOrientation;
if (orientation== UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
if(textField==searchField){
CGRect searchFrame = searchField.frame;
searchFrame.size.width -= 150;
searchFrame.origin.x += 150;
[UIView beginAnimations: #"ShrinkTextField" context: nil];
{
searchField.frame = searchFrame;
[UIView setAnimationDuration: 0.5];
}
[UIView commitAnimations];
}
}
else if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
if(textField==searchField){
CGRect searchFrame = searchField.frame;
searchFrame.size.width -= 150;
searchFrame.origin.x += 150;
[UIView beginAnimations: #"ShrinkTextField" context: nil];
{
searchField.frame = searchFrame;
[UIView setAnimationDuration: 0.5];
}
[UIView commitAnimations];
}
}
}
Related
i want that my textfield should move up in any orientation.
But I am having a problem in landscape right and portrait upside down.
As when i orient it to any one of them my textfield down the view does not go up but the textfield which is on top is going up.
suggest me some solution.
below is the code that i am using for orientation.
please suggest me whole procedure if you can as i am a niwBie to iPhone development.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect textFieldRect=[self.view.window convertRect:textField.bounds fromView:textField];
CGRect viewRect=[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midLine=textFieldRect.origin.y+0.5*textFieldRect.size.height;
CGFloat numerator=midLine-viewRect.origin.y-MINIMUM_SCROLL_FRACTION*viewRect.size.height;
CGFloat denominator=(MAXIMUM_SCROLL_FRACTION-MINIMUM_SCROLL_FRACTION)*viewRect.size.height;
CGFloat heightFraction=numerator/denominator;
if(heightFraction < 0.0)
{
heightFraction=0.0;
}
else if(heightFraction > 1.0)
{
heightFraction=1.0;
}
CGRect viewFrame;
UIInterfaceOrientation orientation=[[UIApplication sharedApplication]statusBarOrientation];
//code for text field editing in landscape an portrait mode
if(orientation==UIInterfaceOrientationPortrait||orientation==UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance=floor(PORTRAIT_KEYBOARD_HEIGHT*heightFraction);
}
else
{
animatedDistance=floor(LANDSCAPE_KEYBOARD_HEIGHT*heightFraction);
}
if (orientation==UIInterfaceOrientationPortrait) {
viewFrame=self.view.frame;
viewFrame.origin.y-=animatedDistance;
}
else if(orientation==UIInterfaceOrientationPortraitUpsideDown){
viewFrame=self.view.frame;
viewFrame.origin.y+=animatedDistance;
}
else if(orientation == UIInterfaceOrientationLandscapeRight){
viewFrame=self.view.frame;
viewFrame.origin.x+=animatedDistance;
}
else if(orientation == UIInterfaceOrientationLandscapeLeft){
viewFrame=self.view.frame;
viewFrame.origin.x-=animatedDistance;
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
In your ViewController override the - willRotateToInterfaceRotation:duration method. This message is called when the user rotates the device. In this method you can then set all your views to be placed in their proper positions. See Responding to View Rotation Events in the reference: UIViewController reference
you could do something like this:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation==UIInterfaceOrientationPortraitUpsideDown){
yourView.frame = CGRectMake(x,y,w,h); //and set the proper coordinate for this view in this orientation
}
and then do it for all your views that are not placed correctly when rotating
I am working on an iPad app that presents a question to the user in a view. When they answer the question, I would like the view to transition to another view that contains the next question. To make it look all fancy, I am trying to add a curl transition to it but the code I wrote does not work can I can't see to find the problem. It does show the correct view but there is no transition animation. What's with that? Here is the method I use to transition:
- (void)pageChangedTo:(NSInteger)page {
if ( (page == currentQuestionNumber) || (page > ( [self.allQuestions count] - 1 ) ) || (page < 0) ) {
return;
}
AskQuestionView *view = [self.questionViews objectAtIndex:page];
UIViewAnimationTransition transition;
if (page > currentQuestionNumber) {
transition = UIViewAnimationTransitionCurlUp;
}
else {
transition = UIViewAnimationTransitionCurlDown;
}
if (self.containerView1.superview) {
self.containerView2 = view;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:transition forView:self.containerView1 cache:YES];
[self.containerView1 removeFromSuperview];
[askQuestionsView addSubview:self.containerView2];
[UIView commitAnimations];
}
else {
self.containerView1 = view;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:transition forView:self.containerView2 cache:YES];
[self.containerView2 removeFromSuperview];
[askQuestionsView addSubview:self.containerView1];
[UIView commitAnimations];
}
currentQuestionNumber = page;
}
Can anyone tell me why this isn't working? I would very much appreciate it!
Set your animation transition forView: _container of_self.containerView2: not the one that's being removed, but the one it's being removed from.
Here are some great tutorials on portrait textfield movement.
One
Two
Three
My View, on the other hand, rotates to both portrait and landscape, and in both orientations the keyboard obscures the textfield... Right now, both portrait, and One of the landscape orientations work.
So I'm wondering how I can include both landscape orientations.
Here's what I'm doing:
-(void) keyboardWillShow:(NSNotification *)notif{
if ([serverIP isFirstResponder]){
if (isPortrait && self.view.frame.origin.y >= 0){
[self setViewMovedVertical:YES];
}
else if (!isPortrait && self.view.frame.origin.x >= 0){
[self setViewMovedHorizontal:YES];
}
}
}
To move the view. Here are the corrosponding methods
#define PORTRAIT_KEY_OFF 216
#define LANDSCAPE_KEY_OFF 140
-(void) setViewMovedVertical:(BOOL)movedUp{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
CGRect rect = self.view.frame;
if (movedUp){
rect.origin.y -= PORTRAIT_KEY_OFF;
rect.size.height += PORTRAIT_KEY_OFF;
}
else{
rect.origin.y += PORTRAIT_KEY_OFF;
rect.size.height -= PORTRAIT_KEY_OFF;
}
self.view.frame = rect;
[UIView commitAnimations];
}
-(void) setViewMovedHorizontal:(BOOL)moved{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
CGRect rect = self.view.frame;
if (moved){
rect.origin.x -= LANDSCAPE_KEY_OFF;
rect.size.width += LANDSCAPE_KEY_OFF;
}
else{
rect.origin.x += LANDSCAPE_KEY_OFF;
rect.size.width -= LANDSCAPE_KEY_OFF;
}
self.view.frame = rect;
[UIView commitAnimations];
}
And here's the method to move it back down
-(IBAction) serverIPDone: (UITextField *) sender{
if ([serverIP isFirstResponder]){
if (self.view.frame.origin.y < 0){
[self setViewMovedVertical:NO];
}
if (self.view.frame.origin.x < 0){
[self setViewMovedHorizontal:NO];
}
[serverIP resignFirstResponder];
}
}
Hope you can help! If I've anti-disambiguated (see what I did there?) the question, please let me know!
FINALLY Figured it out!!!!
Here's what was wrong: The origin did indeed change between the two landscape modes. So all you have to do is detect which version of landscape you are in, and add or subtract based on that!
-(IBAction) serverIPDone: (UITextField *) sender{
if ([serverIP isFirstResponder]){
if (self.view.frame.origin.y < 0){
[self setViewMovedVertical:NO];
}
if (self.view.frame.origin.x != 0){
[self setViewMovedHorizontal:NO];
}
[serverIP resignFirstResponder];
}
}
The previous makes sure that the keyboard is unset.
-(void) setViewMovedVertical:(BOOL)movedUp{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
CGRect rect = self.view.frame;
if (movedUp){
rect.origin.y -= PORTRAIT_KEY_OFF;
rect.size.height += PORTRAIT_KEY_OFF;
}
else{
rect.origin.y += PORTRAIT_KEY_OFF;
rect.size.height -= PORTRAIT_KEY_OFF;
}
self.view.frame = rect;
[UIView commitAnimations];
}
-(void) setViewMovedHorizontal:(BOOL)moved{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
CGRect rect = self.view.frame;
if (moved){
if (leftLandscape)
rect.origin.x -= LANDSCAPE_KEY_OFF;
else
rect.origin.x += LANDSCAPE_KEY_OFF;
}
else{
if (leftLandscape)
rect.origin.x += LANDSCAPE_KEY_OFF;
else
rect.origin.x -= LANDSCAPE_KEY_OFF;
NSLog(#"after: %f",rect.origin.x);
}
self.view.frame = rect;
[UIView commitAnimations];
}
The Previous will do the actual movement of the keyboard. I got rid of the resizing, you can add it back in.
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)x
duration:(NSTimeInterval)duration{
if (UIInterfaceOrientationIsPortrait(x)) {
isPortrait = TRUE;
}
else {
isPortrait = FALSE;
leftLandscape = (x == UIInterfaceOrientationLandscapeLeft);
}
}
The Previous will make sure you set the variables isPortrait and leftLandscape correctly.
It took too long, but I'm finally DONE!!!
i am placing a tableview,textview,buttons in a view as like this.
when ever i click on the textview keypad hides textview.To animate up textview i am writing the code as fallows.
- (void) textViewDidBeginEditing:(UITextView *)textView {
[self animateTextField:textView up:YES];
}
- (void) textViewDidEndEditing:(UITextView *)textView {
[self animateTextField:textView up:NO];
}
- (void) animateTextField: (UITextView*) textView up: (BOOL) up {
const int movementDistance = 80; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: #"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
But it does n't take any effect.
And To hide the keypad i am writing this code
-(void) touchesBegan :(NSSet *) touches withEvent:(UIEvent *)event {
[mytextview resignFirstResponder];
}
it is also does n't take any effect.
can any one please help me.
Thank u in advance.
For resigning keyboard;
Make a ToolBar with bar button and add an IBAction for this and set its y coordinate below the 480(screen hieght)
-(IBAction)hide
{
[mytextview resignFirstResponder];
}
and in viewWillAppear use
myTextView.inputAccessoryView=tlBar;
And add two notification in viewWillAppear for keyboard
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:#selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
[nc addObserver:self selector:#selector(keyboardWillHide:) name: UIKeyboardWillHideNotification object:nil];
and then use these methods for Animation
-(void) keyboardWillShow:(NSNotification *) note
{
if(isAnimate)
[self viewAnimateUpper];
}
-(void)viewAnimateUpper
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.3];
CGRect viewFrame=self.view.frame;
viewFrame.origin.y -=95;//according to you
self.view.frame=viewFrame;
[UIView commitAnimations];
}
-(void)viewAnimatedown
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.3];
CGRect viewFrame=self.view.frame;
viewFrame.origin.y +=95;//according to you
self.view.frame=viewFrame;
[UIView commitAnimations];
}
-(void) keyboardWillHide:(NSNotification *) note
{
if(isAnimate)
{
[self viewAnimatedown];
}
}
Edit:
use textviewShouldBegainEditing
and in this set a boolvariable to yes if your desired textView call this method
isAnimate=YES;
I didn't find a chance to see you view,since my browser says "The image cant be dispalyed,It contains errors."
So try the following options.
Chk whether you have set the delegate of the textField to the files owner.If you have set and still not working,please try the below one.Its like animating the entire view up and down on textedits.
Please make use of the below code.This works for me.What you have to do is double click the .xib file where you want to add text fields.The view along with a window containing file's owner,first responder and a view will also be opened.
Use cmd+shift+l to open the library and add another view.In your .h file add a IBOutlet for the view as IBOutlet UIView *secondview and map to the file's owner.
Now put the text fields whichever has to moved in the second view.Now the default view which will appear when open the .xib file will contain nothing.It will be blank and the controls whichever you have to display will be on the second view.
In the .m file add the second view to the main view as
[self.view addSubview:secondView];
and use this code by customizing the text field names as you wish.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
CGRect viewFrame = self.view.frame;
if(textField==textfield1)
{
[textfield1 resignFirstResponder];
[textfield2 becomeFirstResponder];
}
else if(textField== textfield2)
{
[textfield2 resignFirstResponder];
[textfield3 becomeFirstResponder];
}
else if(textField== textfield3)
{
[textfield3 resignFirstResponder];
[textfield4 becomeFirstResponder];
}
else if(textField== textfield4)
{
[textfield4 resignFirstResponder];
}
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
CGRect viewFrame = secondView.frame;
CGRect textFieldRect =[secondView.window convertRect:textField.bounds fromView:textField];
CGRect viewRect =[secondView.window convertRect:secondView.bounds fromView:secondView];
CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
CGFloat numerator =midline - viewRect.origin.y- MINIMUM_SCROLL_FRACTION * viewRect.size.height;
CGFloat denominator =(MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)* viewRect.size.height;
CGFloat heightFraction = numerator / denominator;
if (heightFraction 1.0)
{
heightFraction = 1.0;
}
UIInterfaceOrientation orientation =[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[secondView setFrame:viewFrame];
[UIView commitAnimations];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
CGRect viewFrame = secondView.frame;
viewFrame.origin.y +=animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[secondView setFrame:viewFrame];
[UIView commitAnimations];
}
Let me know does this worked.
I have a view that contains 10 UITextFields created programatically. I want the following behavior:
When I click on a particular UITextField, the keyboard should hide all the text fields which are visually below the selected text field.
If I have a text field selected and change the device orientation, the text field and the keyboard should both rotate to the proper orientation without the text field losing the selection focus.
I need to control whether the return key in the keyboard is active.
How do I manage these text fields to get these behaviors.
Add your textfield in scrollview and set tag for all the textfield.Than put following code in you application.You must have to enter you textfield position as per your requirements.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
// Begin animations to move TextFields into view.
if (textField.tag == 1) {
[UIView beginAnimations: #"moveField" context: nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration: 0.5];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
self.scrlview.frame = CGRectMake(0,30,320,357);
[UIView commitAnimations];
textfield2.hidden=YES;
textfield3.hidden=YES;
textfield4.hidden=YES;
}
else if(textField.tag == 2)
{
[UIView beginAnimations: #"moveField" context: nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration: 0.5];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
self.scrlview.frame = CGRectMake(0,30,320,357);
[UIView commitAnimations];
textfield1.hidden=YES;
textfield3.hidden=YES;
textfield4.hidden=YES;
}
else if(textField.tag == 3)
{
[UIView beginAnimations: #"moveField" context: nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration: 0.5];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
self.scrlview.frame = CGRectMake(0,25,320,357);
[UIView commitAnimations];
textfield1.hidden=YES;
textfield2.hidden=YES;
textfield4.hidden=YES;
}
else if(textField.tag == 4)
{
[UIView beginAnimations: #"moveField" context: nil];
[UIView setAnimationDelegate: self];
[UIView setAnimationDuration: 0.5];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
self.scrlview.frame = CGRectMake(0,20,320,357);
[UIView commitAnimations];
textfield1.hidden=YES;
textfield2.hidden=YES;
textfield3.hidden=YES;
}
return YES;
}
//Set the objects on the view when device orientation will change.
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation ==UIInterfaceOrientationLandscapeRight) {
// set the views oreintation here for landscapemode.
}
if(interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown ||
interfaceOrientation == UIInterfaceOrientationPortrait) {
//set the views oreintation here for Portraitmode.
}
}
//Delegate called when orientation will change
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}