Orientation problem - iphone

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

Related

Back ground resizing on keyboard visiblity

I'm using scroll view in my application ,since when i click on dob text-field the datepicker view is showing as a pop up ,on further when i click in continuous text field the view is being like in the image,Here my code,
For date picker visibility.
UIDatePicker pop up after UIButton is pressed
For keyboard orientation
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[dob resignFirstResponder];
if (txt1.textColor == [UIColor lightGrayColor]) {
txt1.text = #"";
txt1.textColor = [UIColor blackColor];
}
if ([textField isEqual:dob])
{
[self but];
[dob resignFirstResponder];
//return NO;
}
//[self animateTextField:textField up:YES];
[textField setClearButtonMode:UITextFieldViewModeWhileEditing];
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.1 * 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;
}
UIInterfaceOrientation orientation =
[[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait ||
orientation == UIInterfaceOrientationPortraitUpsideDown)
{
animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
}
else
{
animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
}
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
//[self animateTextField:textField up:NO];
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += animatedDistance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return [textField resignFirstResponder];
return [txt1 resignFirstResponder];
}
Can any one help me to clear.
You need to resize your scrollview when the key board appears.
this can be done by adding:
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:#selector(keyboardShown) name:UIKeyboardDidShowNotification object:nil];
[center addObserver:self selector:#selector(keyboardHidden) name:UIKeyboardWillHideNotification object:nil];
in the viewDidLoad.
Then define the methods keyboardShown and keyboardHidden in your implementation file.
These methods will be called automatically when keyboard appears and disappears.
In these methods resize your background view accordingly. since you are using scroll view please mind the scrollView's contectView size also. as its different from the view's frame size.
For the basic problem of having a scroll view and needing to move its contents when the keyboard appears, I have found this open source scroll view class by Michael Tyson to be very useful.
Basically, you just add the TPKeyboardAvoidingScrollView class to your project, and use it where you would normally use a UIScrollView. The child views that you add to the TPKeyboardAvoidingScrollView can be UITextField objects, if you like. When you tap those fields to begin editing, and the keyboard appears, the TPKeyboardAvoidingScrollView container will choose an appropriate scroll position so that the field that's being edited is not hidden by the keyboard, and you won't see black bars like you have in your screen shot.
I think i get the problem.
jst for example, in ur register page, many textfields and button for DOB.
So, basically when any textfield editing and after that instead of return keyboard, user press button of DOB.
so u have to first resignFirstRespoder ur all textfields.
Problem is when u startEditing frame set to top and endEditing set to bottom but when u click to button endEditing not called so frame not set to bottom. And again u startEditing frame again set to top so problem aries.
I hope this help...

Placing and Moving Views on Rotation (UIView)

What's the "correct" way of exactly placing and moving views when an app rotates? That is, how can I have fine-grained control of the position, size, and reflow of my views when the UI rotates from portrait to landscape orientation (or vice-versa)? I think my two options are:
Use two superviews (portrait and landscape). On rotation: toggle between them.
Use one superview. On rotation: change each subview's frame, bounds, and center properties.
If you have two views with distinct enough layouts and elements, then the first way might be good enough. If your two views are essentially the same thing sized for different orientations, the second way is probably a better way to do it using only one view.
I suspect the former could be done with IB and the latter should be done programmatically.
To have fine-grained control over the position and size of your subviews when the iPhone rotates, change the frame of the subviews in the UIViewController method willAnimateRotationToInterfaceOrientation:duration:. This method is called within an animation block, so all the changes to your subviews' frames that you make inside of it are animated.
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
// Portrait frames
self.subviewA.frame = CGRectMake(x, y, width, height);
self.subviewB.frame = CGRectMake(x, y, width, height);
self.subviewC.frame = CGRectMake(x, y, width, height);
} else {
// Landscape frames
self.subviewA.frame = CGRectMake(x, y, width, height);
self.subviewB.frame = CGRectMake(x, y, width, height);
self.subviewC.frame = CGRectMake(x, y, width, height);
}
}
Here's one idea. I worry that the animations will work funny, but try it and see.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toOrientation
duration:(NSTimeInterval)duration {
if (toOrientation == UIInterfaceOrientationLandscapeLeft ||
toOrientation == UIInterfaceOrientationLandscapeRight) {
[UIView beginAnimations:nil context:NULL]; {
[UIView setAnimationDuration:1.0];
}
[UIView setAnimationDelegate:self];
[viewA setFrame:CGRectMake(?,?,?,?)];
[viewB setFrame:CGRectMake(?,?,?,?)];
[viewC setFrame:CGRectMake(?,?,?,?)];
} [UIView commitAnimations];
} else if (toOrientation == UIInterfaceOrientationPortrait ||
toOrientation == UIInterfaceOrientationPortraitUpsideDown) {
[UIView beginAnimations:nil context:NULL]; {
[UIView setAnimationDuration:1.0];
}
[UIView setAnimationDelegate:self];
[viewA setFrame:CGRectMake(?,?,?,?)];
[viewB setFrame:CGRectMake(?,?,?,?)];
[viewC setFrame:CGRectMake(?,?,?,?)];
} [UIView commitAnimations];
}
I have an idea which is working properly for me where I am using a small view on a view where it rotates itself when orientation of device changes. Use one notifier then in the method change the orientation.
#define DegreesToRadians(x) (M_PI * x / 180.0)
.......
[[NSNotificationCenter defaultCenter] addObserver:showIndicator
selector:#selector(setProperOreintation)
name:UIDeviceOrientationDidChangeNotification
object:nil];
.......
-(void)setProperOrientation {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
if (orientation == UIDeviceOrientationPortraitUpsideDown)
self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DegreesToRadians(180));
else if (orientation == UIDeviceOrientationLandscapeLeft)
self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DegreesToRadians(90));
else if (orientation == UIDeviceOrientationLandscapeRight)
self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, DegreesToRadians(-90));
[UIView commitAnimations]; }
Here instead of rotate u can use translate or scale
There is a lot solutions for that. One of them is animations for controls as you read before. Another option is prepare 2 UIView one for portrait mode and another for landscape mode. And on switch orientation - load proper UIView. That's the way i used in my applications. Because sometimes differences between landscape and portrait is huge.
In simple cases is enough to set up correct autoresizingMask for subviews. Read about it. It works really nice.

Simple iPad question - Safari browser - Google search bar

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];
}
}
}

How to create a collapsible UIView

I need to create a expandable and collapsible UIView of some sort and am not able to pay for a third party control.
This is basically how I would like it to behave:
At the top there should be a UIButton (or similar) that allows the user to toggle between expanded and collapsed.
When expanded I want to be able to place other UIView (e.g. calendar)and when collapsed the surrounding controls should move up.
Does anyone have any ideas how to implement this simply - noob here :(
Subclass a ViewController and have two methods that your button can fire like 'collapse' and 'expand', this might get you started: You can assign new selectors to UIButtons dynamically:
[button addTarget:self action:#selector(eventMethod:)
forControlEvents:UIControlEventTouchUpInside];
Code:
#define COLAPSED_HEIGHT 30
-(void)expand
{
CGRect s= [self getScrerenBoundsForCurrentOriantation];
CGRect f = self.view.frame;
f.origin.y =s.size.height-self.view.frame.size.height;
[UIView beginAnimations:#"expand" context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationFinished:finished:context:)];
self.view.frame=f;
//CHANGE YOUR EXPAND/COLLAPSE BUTTON HERE
[UIView commitAnimations];
self.thumbScrollerIsExpanded=YES;
}
-(void)collapseView
{
//re-factored so that this method can be called in ViewdidLoad
CGRect s= [self getScrerenBoundsForCurrentOriantation];
CGRect f = self.view.frame;
f.origin.y =(s.size.height-COLAPSED_HEIGHT);
self.view.frame = f;
self.thumbScrollerIsExpanded=NO; //thumbScrollerIsExpanded is a BOOL property
}
- (void)collapse
{
[UIView beginAnimations:#"collapse" context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationFinished:finished:context:)];
[self collapseView];
//CHANGE YOUR EXPAND/COLLAPSE BUTTON HERE
[UIView commitAnimations];
}
-(CGRect)getScrerenBoundsForCurrentOriantation
{
return [self getScrerenBoundsForOriantation:[[UIDevice currentDevice] orientation]];
}
-(CGRect)getScrerenBoundsForOriantation:(UIInterfaceOrientation)_orientation
{
UIScreen *screen = [UIScreen mainScreen];
CGRect fullScreenRect = screen.bounds; // always implicitly in Portrait orientation.
if (UIInterfaceOrientationIsLandscape(_orientation))
{
CGRect temp;
temp.size.width = fullScreenRect.size.height;
temp.size.height = fullScreenRect.size.width;
fullScreenRect = temp;
}
return fullScreenRect;
}
- (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context
{
if ([animationID isEqualToString:#"expand"])
{
//example
}
else if ([animationID isEqualToString:#"collapse"])
{
//example
}
}
You could try adding a UIView (either in xib or programmatically) off screen, then use a UIView animation to slide it into your main viewing area.
The button would have an IBAction which would toggle the animation (slide in/slide out). You can slide it off screen then set UIView's hidden property to true. When you recall the IBAction, have it check if the view's hidden property is true. If it is, you know to play the animation of it sliding in, if not, then you play the animation of sliding out.

scroll to a specific textfield in a scrollview/scrollview stop scrolling when keyboard is on screen

I got stuck in here,
I have a custom scrollview in a view this scroll view has an add field button which lets user to add new text field to the scrollview. When user taps on a particular textfield keyboard appears and hide the textfield, to overcome this I followed UICatalog example, but it moves the whole scrollview up
to prevent this I followed UICatalog example and did this
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if (sender.frame.origin.y>109) {
moveScrollViewUpBy=(sender.frame.origin.y-109+10);
[self viewMovedUp:YES];
}
}
-(void)viewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect rect = formScrollView.frame;
if (movedUp)
{
if(rect.origin.y == 0.0f){
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
}
else
{
if(rect.origin.y != 0.0f){
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
}
self.formScrollView = rect;
[UIView commitAnimations];
}
here
#define kOFFSET_FOR_KEYBOARD 160.0
but this shifts the scroll view up,
I want that when i tap on a textfield down below in scroll view... scroll view scrolls and that textfield appears....
is it possible to do so....otherwise suggest me some other solution
I have one more query srollview just stop scrolling while the keyboard stays on screen. Is there any way to overcome this
You probably just want to set the scrollView's contentOffset property, rather than adjust its bounds.
Implement the UITextViewDelegate and do the following:
- (void)textViewDidBeginEditing:(UITextView *)textView {
keyboardShowing = YES; //helper ivar
[self sizeToOrientation];
[self.scrollView scrollRectToVisible:textView.frame animated:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
keyboardShowing = NO;
[self sizeToOrientation];
}
Helper method:
//fit to the appropriate view sizes
- (void)sizeToOrientation {
CGSize size;
if( keyboardShowing )
size = CGSizeMake(320, 190); //make room for keyboard
else
size = CGSizeMake(320, 420); //full height with tabbar on bottom
self.scrollView.frame = CGRectMake(0, 0, size.width, size.height);
}
This works well for me.