View frame shows unexpected results on orientation change - iphone

In portrait orientation, i have pushed the view contents up when keyboard appears and pushed it down on return key press.The view's frame is x=0, y=20 (status bar placed). In xib, the view size is set to freeform. When changed to landscape orientation, the new view's frame's origin is x=20 y=0. Ideally it should be x=0 and y=20 right? Below is the code.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
// [self.view setFrame:CGRectMake(0, 20, 320, 460)];
}
else if(toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight )
{
// [self.view setFrame:CGRectMake(0, 20, 480, 300)];
}
return YES;
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight )
{
[lblFirstName setFrame:CGRectMake(100, 134, 84, 21)];
[lblLastName setFrame:CGRectMake(100, 193, 83, 21)];
[txtFirstName setFrame:CGRectMake(273, 129, 142, 31)];
[txtLastName setFrame:CGRectMake(273, 188, 142, 31)];
[btnSubmit setFrame:CGRectMake(194, 243, 93, 37)];
}
else if(toInterfaceOrientation==UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
[lblFirstName setFrame:CGRectMake(37, 198, 84, 21)];
[lblLastName setFrame:CGRectMake(37, 282, 83, 21)];
[txtFirstName setFrame:CGRectMake(165, 193, 127, 31)];
[txtLastName setFrame:CGRectMake(165, 277, 127, 31)];
[btnSubmit setFrame:CGRectMake(114, 349, 93, 37)];
}
}
//Hide keypad on background touch
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if(self.view.frame.origin.y<0)
{
[self setViewMovedUp:NO];
}
[self.view endEditing:YES];
//[self keyboardWillHide];
}
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if ([sender isEqual:txtLastName])
{
//move the main view, so that the keyboard does not hide it.
NSLog(#"view frame original is %f %f",self.view.frame.origin.x,self.view.frame.origin.y);
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
}
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
[UIView animateWithDuration:0.3 animations:^{
CGRect rect = self.view.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden comes above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
rect.origin.y -= OFFSET_FOR_KEYBOARD;
rect.size.height += OFFSET_FOR_KEYBOARD;
}
else
{
//revert back to the normal state.
rect.origin.y += OFFSET_FOR_KEYBOARD;
rect.size.height -= OFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
NSLog(#"view frame modified is %f %f",self.view.frame.origin.x,self.view.frame.origin.y);
}];
}
//Return key click handled.
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if(self.view.frame.origin.y<0)
{
[self setViewMovedUp:NO];
}
[textField resignFirstResponder];
return YES;
}

I got the same issue in iOS7.
At the same time the same code works fine in iOS8.
To fix this issue you need to shift view.bounds instead of view.frame

Related

iOS/Xcode - Toggle button changing position

I want a button that toggles the position of an element on click.
My current code:
-(IBAction)menuTouched{
// Push menu
UITableView * sideMenu = [[UITableView alloc] initWithFrame:CGRectMake(1060, 88, 63, 661)];
sideMenu.backgroundColor = [UIColor redColor];
[self.view addSubview:sideMenu];
// Animate
[UIView animateWithDuration:1.25 animations:^{
sideMenu.frame = CGRectMake(960, 88, 63, 661);
}];
}
When clicking the button it animates the tableview in just like I want to. But now I want to animate the tableview out by pressing the exact same button. So in short I want the button to toggle in and out a tableview by changing the X position. What is the best/easiest approach?
Thanks in advance.
inside your .h file add
UITableView * sideMenu;
BOOL checkInOut;
inside .m file add
- (void)viewDidLoad
{
[super viewDidLoad];
checkInOut=False;
// Push menu
sideMenu = [[UITableView alloc] initWithFrame:CGRectMake(1060, 88, 63, 661)];
sideMenu.backgroundColor = [UIColor redColor];
[self.view addSubview:sideMenu];
}
-(IBAction)menuTouched
{
checkInOut=!checkInOut
if(checkInOut)
{
// Animate
[UIView animateWithDuration:1.25 animations:^{
sideMenu.frame = CGRectMake(960, 88, 63, 661);
}];
}
else
{
[UIView animateWithDuration:1.25 animations:^{
sideMenu.frame = CGRectMake(1060, 88, 63, 661);
}];
}
}
You will need a bool to store the state where you are, but you can just use the button.selected state for that.. Something like that:
- (IBAction)menuTouched:(id)sender
{
sender.selected = !sender.selected;
if (sender.selected)
{
// toggle on stuff
}
else
{
// toggle off stuff
}
}
Try it....
[UIView beginAnimations: nil context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: 0.5];
myButton.frame = CGRectMake(0,420,320,120);
[UIView commitAnimations];
Hope i helped.
you can perform the same animation with different frame as you set previously
sideMenu.frame = CGRectMake(1060, 88, 63, 661);
with the check to see have you togged the table in or out to perform respective action.
Hope this helps.
You have to receive as UIButton reference instead of id
- (IBAction)menuTouched:(UIButton *)sender
{
sender.selected = !sender.selected;
if (sender.selected)
{
[UIView animateWithDuration:1.25 animations:^
{
UITableView * sideMenu = [[UITableView alloc] initWithFrame:CGRectMake(1060, 88, 63, 661)];
sideMenu.backgroundColor = [UIColor redColor];
[self.view addSubview:sideMenu];
sideMenu.frame = CGRectMake(960, 88, 63, 661);
}];
}
else
{
[UIView animateWithDuration:1.25 animations:^{
[sideMenu removeForSuperView];
}];
}
}
1.set a flag bit to represent UITableView's current state.The statement need 3 variables.
BOOL isShow;
UITableView *sideMenu;
CGFloat posX;
2.initial setting in viewDidLoad
-(void)viewDidLoad {
isShow=NO;
//to do something...
sideMenu = [[UITableView alloc] initWithFrame:CGRectMake(1060, 88, 63, 661)];
sideMenu.backgroundColor = [UIColor redColor];
[self.view addSubview:sideMenu];
}
3.What UITableView shows is just the change of X-coordinate of frame.so you can calculate posX depend on toggles 'state.and notice don't create UITableView at each time clicking.put the UITableView creat code on viewDidLoad function.
-(IBAction)menuTouched{
posX=isShow ? 1060 : 960
// Animate
[UIView animateWithDuration:1.25 animations:^{
sideMenu.frame = CGRectMake(posX, 88, 63, 661);
}];
isShow=!isShow; //boggle button
}

iPhone Orientation change frame of view

I want to set position of UILable programatically depend on orientation. But When I get back to Portrait, it doesn't work.
Here is my code :
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown)
{
lblUserName.frame = CGRectMake(20, 200, 280, 44);
lblPassword.frame = CGRectMake(20, 246, 280, 44);
}
else
{
lblUserName.frame = CGRectMake(20, 220, 280, 44);
lblPassword.frame = CGRectMake(20, 266, 280, 44);
}
}
There are 2 possibilities.Either you can set the label programatically.And check the condition for orientation in the - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{}
method.Otherwise you can use auto resizing mask.
try with this IF condition:
if ( UIInterfaceOrientationIsPortrait(toInterfaceOrientation))
{
}
else {}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//write code here
return YES;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
//write code here
}
Use this two methods for set your label when rotate device.

UISearchBar won't hide keyboard on resignFirstResponder when moving to another view controller

I have a UISearchBar that behaves normally - the keyboard goes away if I hit "Search" or "Cancel".
However, when I push a new view controller on my navigation stack, if the keyboard is open, it won't close. It stays there in the old view controller, and if I navigate back to it the keyboard is still shown.
I'm stumped because my searchBarShouldEndEditing method is called as expected, and I do [activeSearchBar resignFirstResponder]. This works for "Search" or "Cancel", but not when it's triggered by the view disappearing.
My delegate code:
#pragma mark Search bar delegate methods__________________________
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)activeSearchBar
{
NSLog(#"searchBarShouldBeginEditing");
[activeSearchBar setShowsCancelButton:TRUE animated:YES];
if (!showSearchType)
return TRUE;
if([UIView respondsToSelector:#selector(animateWithDuration:animations:)]) {
// iOS 4.0 and later
[UIView animateWithDuration:0.3 animations:^ {
searchTypeView.frame = CGRectMake(0, 44, 320, 69);
searchTypeView.bounds = CGRectMake(0, 0, 320, 69);
grayBg.alpha = 0.6;
}];
} else {
// Before iOS 4.0
searchTypeView.frame = CGRectMake(0, 44, 320, 69);
searchTypeView.bounds = CGRectMake(0, 0, 320, 69);
grayBg.alpha = 0.6;
}
self.frame = CGRectMake(0, 0, 320, 113);
[self bringSubviewToFront:searchTypeView];
[self bringSubviewToFront:activeSearchBar];
return TRUE;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)activeSearchBar
{
NSLog(#"searchBarShouldEndEditing");
if ([activeSearchBar isFirstResponder]) {
NSLog(#"activeSearchBar isFirstResponder");
}
[activeSearchBar resignFirstResponder];
[activeSearchBar setShowsCancelButton:FALSE animated:YES];
if (!showSearchType)
return TRUE;
if([UIView respondsToSelector:#selector(animateWithDuration:animations:)]) {
// iOS 4.0 and later
[UIView animateWithDuration:0.3 animations:^ {
searchTypeView.frame = CGRectMake(0, 9, 320, 69);
searchTypeView.bounds = CGRectMake(0, 0, 320, 0);
grayBg.alpha = 0;
}];
} else {
// Before iOS 4.0
searchTypeView.frame = CGRectMake(0, 9, 320, 69);
searchTypeView.bounds = CGRectMake(0, 0, 320, 0);
grayBg.alpha = 0;
}
self.frame = CGRectMake(0, 0, 320, 44);
return TRUE;
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)activeSearchBar {
NSLog(#"searchBarTextDidEndEditing");
if ([activeSearchBar isFirstResponder]) {
NSLog(#"activeSearchBar isFirstResponder");
}
[activeSearchBar resignFirstResponder];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)activeSearchBar
{
NSLog(#"searchBarCancelButtonClicked");
[activeSearchBar resignFirstResponder];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)activeSearchBar
{
NSLog(#"searchBarSearchButtonClicked");
self.query = searchBar.text;
[activeSearchBar resignFirstResponder];
[searchView startSearch];
}
This outputs:
2011-12-07 20:00:33.061 MyApp[55725:307] searchBarShouldEndEditing
2011-12-07 20:00:33.063 MyApp[55725:307] activeSearchBar isFirstResponder
2011-12-07 20:00:33.066 MyApp[55725:307] searchBarTextDidEndEditing
Thanks for any ideas!
Also you can : declare searchBar variable in your .h file, make property etc... then on your button click event method, that pushes another view, write first line :
[yourSearchBar resignFirstResponder];
OK, I found a solution, although it's not great.
In the parent view controller, I put the following line BEFORE anything that would trigger a new view controller to be pushed on the navigation stack:
[self.view endEditing:YES];
This seems a bit fragile and error-prone... I would love to know if there's a better way.

What is difference between self.view.frame and self.superview.frame and how to use them?

I would like to know that what is difference between these both lines of code?
self.view.frame = CGRectMake(0, 0, 320, 480);
self.view.superview.frame = CGRectMake(0, 0, 800, 900);
and I want to change the view frame when my orientation will change, because it will change the position of labels, and I want them in middle of screen, can anyone guide me ?
I am using following delegate method, for orientation, but it is not working with
self.view.frame
but it is working ok with following line
self.view.superview.frame
See the following code
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
//return (interfaceOrientation == UIInterfaceOrientationPortrait);
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
NSLog(#"LEFT");
self.view.frame = CGRectMake(100, 0, 480, 320);
NSLog(#"Show self.view.frame: %#", NSStringFromCGRect(self.view.frame));
// self.view.superview.frame = CGRectMake(-50, -70, 800, 900);
[button setFrame:CGRectMake(340, 320, 100, 30)];
}
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"RIGHT");
self.view.frame = CGRectMake(0, 0, 320, 480);
NSLog(#"Show self.view.frame: %#", NSStringFromCGRect(self.view.frame));
//self.view.superview.frame = CGRectMake(10, 90, 800, 900); //It is working if I will uncomment it
[button setFrame:CGRectMake(250, 300, 100, 30)];
}
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
self.view.frame = CGRectMake(0, 0, 320, 480);
//self.view.superview.frame = CGRectMake(0, 0, 800, 900);//It is working if I will uncomment it
[button setFrame:CGRectMake(250, 400, 100, 30)];
}
return YES;
}
self.view is the view of self (if we are talking about viewControllers).
self.view.superview is the view that is holding self.view.
So, in short, if you add a view to the window the superview of that view will be the window.
Setting the frame will fail if the autoresize mask isn't set correctly.
As a generic statement, the first line is trying set the frame of the current viewController's view that this code is written in.
The second line is trying to set the frame of the parent view of the view of the current viewController's view.
What this exactly means, and which one you should be using I'm afraid depends on the view hierarchy you have set up in your application.

Autoresize UIScrollView

I made a UIViewController, which programatically generates a UIScrollView. Everything's fine, but when I rotate the Device, the UIScollView should resize so it takes the complete width of my View.
Is there a way to do that without rebuilding the complete UIScrollView ?
Thx a lot !
Sebastian
This is called in my viewDidLoad:
-(void)buildmyScroller {
myScroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 800, 768, 100)];
//...adding some subviews to myScroller
thumbScroller.contentSize = CGSizeMake(3000, 100);
[[self view] addSubview:myScroller];
}
Then I tried to resize myScroller with this, when I used setFrame, I said myScroller would not respond to it... :
-(void)changemyScroller {
UIInterfaceOrientation interfaceOrientation = self.interfaceOrientation;
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
[thumbScroller setFrame:CGRectMake(0, 805, 768, 150)];
}
else if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
thumbScroller.frame = CGRectMake(0, 805, 768, 150);
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft){
thumbScroller.frame = CGRectMake(0, 549, 1024, 150);
}
else if (interfaceOrientation == UIInterfaceOrientationLandscapeRight){
thumbScroller.frame = CGRectMake(0, 549, 1024, 150);
}
}
And called the method in didAnimateFirstHalf... cause I'm not shure where else to call it.
Thx a lot again !!
[scrollView setFrame:CGRectmake(x, y, width, height)];
//Maybe you need to do the same for the content of the scrollView to make it fit your layout
should do it. You can wrap that in an UIAnimation block if it need to be a transition.
Try this:
if(self.rowNumber == 0){
/******************* Scroller Setup *****************/
// how many pages
int pageCount = 5;
//set up the scrollView
UIScrollView *scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 768, 960)];
// support for Landscape Orienation
if(UIInterfaceOrientationLandscapeLeft){
[scroller setFrame:CGRectMake(0,0,1024, 704)];
}
if(UIInterfaceOrientationLandscapeRight){
[scroller setFrame:CGRectMake(0,0,1024, 704)];
}