issues with Xcode 4.5 while changing iPad's orientation - iphone

Am facing this problem ever since i upgraded to XCODE 4.5.
I have various UI elements
UIButton *button1;
UIButton *button2;
UIButton *button3;
- (void)viewDidLoad
{
button1 =[[UIButton alloc]init ];
button1.backgroundColor=[UIColor yellowColor];
[self.view addSubview:button1];
button2 =[[UIButton alloc]init ];
button2.backgroundColor=[UIColor yellowColor];
[self.view addSubview:button2];
button3 =[[UIButton alloc]init ];
button3.backgroundColor=[UIColor yellowColor];
[self.view addSubview:button3];
}
whose frames are declared in
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation==UIInterfaceOrientationPortrait ||[interfaceOrientation==UIInterfaceOrientationPortraitUpsideDown )
{
button1.frame=CGRectMake(10,10,10,10);
button2.frame=CGRectMake(10,30,10,10);
button3.frame=CGRectMake(10,50,10,10);
}
if(interfaceOrientation ==UIInterfaceOrientationLandscapeLeft ||interfaceOrientation==UIInterfaceOrientationLandscapeRight)
{
button1.frame=CGRectMake(20,10,10,10);
button2.frame=CGRectMake(20,30,10,10);
button3.frame=CGRectMake(20,50,10,10);
}
return YES;
}
but the frames are not set in Xcode 4.5..
in the previous versions it worked fine.
i need auto sizing badly in my app. so help me.

You should need to implement new methods(introduced in 'ios 6' ) in viewController for orientation
- (BOOL)shouldAutorotate
{
return TRUE;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
And Modify You Code place your code inside the in Below Method
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration
{
}
Also check your window, you need to add the controller on window as rootviewController rather than addSubview like below
self.window.rootViewController=viewController;

Some classes will automatically resize when the device orientation changes, e.g. from portrait to landscape, but others (like UILabel and UITextView) require a little configuration.
The setAutoresizesSubviews property controls whether each object will resize automatically when their bounds change.
The setAutoresizingMask property controls how each object resizes automatically. A UILabel only has to worry about resizing its width, but since a UITextView is scrollable it needs to resize both its width and height when its bounds change.
You should also make sure the shouldAutorotateToInterfaceOrientation method is configured to return YES; otherwise your view won’t do anything when the device orientation changes!
Sample Code:
[self.myLabel setAutoresizesSubviews:YES];
[self.myLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[self.myTextView setAutoresizesSubviews:YES];
[self.myTextView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
For more details you can visit here

Related

Repositioning controls when the orientation changes

I know Auto Layout can be used to make the sizes and position consistent when the orientation changes. Is it possible to completely change the layout when the orientation changes?
For example, please look at the below wire-frame of a simple login screen in portrait mode.
Now if I rotate the device, I want to completely re-position the controls.
Can this kind of a thing be done by using Auto Layout? If not, how should I go about this?
Thank you.
In your case it can be achieved by two methods, instead of reframing every component you can group the controls like the following..
Parent View -> User Info View -> All User Info controls.. By doing this you will have to just reframe the User Info View not all the controls..
Then only Logo and Company name left to reframe.. Total 3 controls to reframe if you group your controls..
Create two views one for Portrait and other for Landscape mode, and just add and remove on rotations.. this is the fastest way as you won't have to readjust the frame by tedious code.
Hope above helps.
you cant set frames differently : -
-(void)setFramesForPotrait
{
// set frames here
}
-(void)setFramesForLandscaeMode
{
// set frames here
}
-(bool)shouldAutorotate.....
{
return Yes
}
-()willAutoRotate......
{
if(orientation = uiinterfaceOrientationPotrait)
{
[self setFramesForPotrait];
}
else
{
[self setFramesForLandscape];
}
I've had the same problem and here's what I've found so far.
The approach I'm using is having two sets (potentially multiple) sets of constraints for different screen sizes or orientations. So I just design for portrait and connect all constraints that are portrait-specific to a IBOutletCollection:
Then switch the VC orientation in InterfaceBuilder to Landscape and add the required constraints for this orientation and connect to the corresponding outlet:
Then in code I'm removing or adding the constraints as required:
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self updateViewConstraints];
}
- (void)updateViewConstraints
{
[super updateViewConstraints];
if (self.view.frame.size.width >= kSize * 2 + kPadding * 3)
{
[self.view removeConstraints:self.constraintsForPortrait];
[self.view addConstraints:self.constraintsForLandscape];
} else
{
[self.view removeConstraints:self.constraintsForLandscape];
[self.view addConstraints:self.constraintsForPortrait];
}
}
You can achieve similar results with this code, basing your adding/removing of constraints on orientation instead of frame size:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self updateViewConstraints];
}
But keeping in mind that Apple is rumored to release devices with different screen aspect ratios and obsoleting the UIInterfaceOrientation and rotation events, it might be worth preparing in advance.
Will see what future brings.
The downside of the approach is that that Xcode will be complaining about the design being ambiguous, which it actually is, since Xcode doesn't know we'll be removing the ambiguity at runtime. To tackle that you could set the priority of the constraints to be optional for all other orientations that you're not designing for at this particular moment (e.g. if you're designing for Portrait then optionalize the constraints for Landscape).
When using autolayout you can override updateViewConstraints to modify the layout on orientation change:
- (void)updateViewConstraints{
[super updateViewConstraints];
//portrait
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
}
//landscape
else{
//
}
}
It can be done with layout constraints something like I have below. This doesn't quite work, because your sketch doesn't quite work -- your landscape view is too long compared with what you really get in landscape. You would have to shorten the login text fields for everything to fit, but this should give you an idea how it's done. The buttonWidth constraint shows how to have a negative correlation between the width of the view and the width of a button -- that is, the button's width will be less in landscape than in portrait. I have several IBOutlets to constraints that I reference in the code. I can describe them for you if you're interested, but I'll just throw this out there for now:
#implementation ViewController {
IBOutlet NSLayoutConstraint *buttonWidth;
IBOutlet NSLayoutConstraint *logoTop;
IBOutlet NSLayoutConstraint *logoAlignToLabel;
IBOutlet NSLayoutConstraint *logoSpaceToLabel;
IBOutlet NSLayoutConstraint *coNameToButtonAlignment;
IBOutlet UIButton *b;
IBOutlet UIImageView *logo;
IBOutlet UILabel *coName;
NSLayoutConstraint *con2;
NSArray *cons1;
}
- (void)viewDidLoad {
[super viewDidLoad];
[b removeConstraint:buttonWidth];
buttonWidth = [NSLayoutConstraint constraintWithItem:b attribute:NSLayoutAttributeWidth relatedBy:0 toItem:self.view attribute:NSLayoutAttributeWidth multiplier:-.2193 constant:350];
[self.view addConstraint:buttonWidth];
[self.view layoutSubviews];
}
- (void)updateViewConstraints{
[super updateViewConstraints];
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
if (con2 != nil) {
[self.view removeConstraints:cons1];
[self.view removeConstraint:con2];
[self.view addConstraints:#[logoAlignToLabel,logoSpaceToLabel,logoTop,coNameToButtonAlignment]];
}
}else{
NSLog(#"Landscape");
[self.view removeConstraints:#[logoAlignToLabel,logoSpaceToLabel,logoTop,coNameToButtonAlignment]];
cons1 = [NSLayoutConstraint constraintsWithVisualFormat:#"|-8-[logo]-4-[coName]" options:NSLayoutFormatAlignAllCenterY metrics:0 views:#{#"logo":logo, #"coName":coName}];
con2 = [NSLayoutConstraint constraintWithItem:logo attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
[self.view addConstraints:cons1];
[self.view addConstraint:con2];
}
}
On rotation the logo and company name label have their constraints removed, and new ones put in place. The new constraint for the button, that I put on in viewDidLoad, takes care of rotation automatically, so I don't have to adjust it at all during the rotation.

how to set the label postion from portrait to landscape in a view

i am doing application where i have taken two views Portrait and Landscape. i am creating a label programitically and calling it by parameter passing.As i want the position of the label to be changed in the landscapeView so i am taking two views.Instead i want to do in a SingleView
instead of using two views i want to have only one view and set the label position accordingly in portrait and landscape.
so please suggest me how to have only one view and change the textLabel position according to the view..please suggest me with sample code.
At present i am using the below code
[self.portraitView addSubview:[self createLabel:CGRectMake(450,140,60,20):#"Ratings:"]];
[self.landscapeView addSubview:[self createLabel:CGRectMake(600,140,60,20):#"Ratings:"]];
-(UILabel*)createLabel:(CGRect)frame :(NSString*)labelTitle {
UILabel *myLabel = [[UILabel alloc] initWithFrame:frame];
[UIFont fontWithName:#"Arial" size:13];
myLabel.text = labelTitle;
}
Make your UILabel *myLabel a class variable by declaring it in your .h file.
Call the createLabel method in the viewDidLoad method of your viewController based on the correct device orientation.
-(void) viewDidLoad
{
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation
if(orientation == UIDeviceOrientationPortrait)
CGRect frame = CGRectMake(450,140,60,20);
else
CGRect frame = CGRectMake(600,140,60,20);
myLabel = [[UILabel alloc] initWithFrame:frame];
[UIFont fontWithName:#"Arial" size:13];
myLabel.text = labelTitle;
}
Reset the frame in this method
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationLandScape)
{
mylabel.frame = CGRectMake(600,140,60,20); //your landscape frame
mylabel.text = #"Ratings:";
}
else
{
mylabel.frame = CGRectMake(450,140,60,20); // your portrait frame
mylabel.text = #"Ratings:";
}
}
You will need to dig around a little bit for covering all the possible orientations in this method.
Cheers!!!
in your code there is a method called
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(interfaceOrientation == UIInterfaceOrientationLandScape)
//set label frame here
}
Implement the following two methods in your viewcontroller.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
and
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
In willRotateToInterfaceOrientation:duration: method, set the required frame to the label instance.
You should set the labels frame in the layoutSubviews method of the UILabel's superview and check the superviews bounds or the interface orientation to determine the appropriate frame for the label. If you also use autoresizingMask on the UILabel correctly, the transition will be animated nicely.
Also: why do you use two views? instead of applying different layouts to one?

iphone: uiscrollview doesn't scroll? but contentsize is set..?

hey people,
I have some data and want to show this in a new view inside a navigation-stack.
I created some new viewcontroller class with XIB file. Then I edited the XIB file and placed the following hierachy:
1 files owner
2 first responder
3 scrollview
3.1 view
3.1.1 label1
3.1.2 label2
3.1.3 label3
3.1.4 image4
I arranged the labels and the image. the content of the labels may differ and they should size dynamically. I also did the IBOutlets in the viewcontroller class and connected everything correctly. the files owner's view delegate is set to view..
then I load the viewcontroller and I do in the "viewDidLoad" - method the following:
- (void)viewDidLoad {
[super viewDidLoad];
self.currentPageURL.text = [self.offerItem objectForKey: #"page-url"];
self.currentPrice.text = [self.offerItem objectForKey: #"price"];
self.currentRank.text = [self.offerItem objectForKey: #"rank"];
self.currentName.text = [self.offerItem objectForKey: #"name"];
self.currentProducerName.text = [self.offerItem objectForKey: #"producer-name"];
self.currentDescription.text = [self.offerItem objectForKey: #"description"];
self.imageViewForImage.image = [helperClass resizeImage:[self.offerItem objectForKey: #"picture"] forSize:CGSizeMake(280.0, 280.0) ];
[theScrollview setScrollEnabled:YES];
[theScrollview setContentSize:CGSizeMake(320, 1200)];
[theScrollview flashScrollIndicators];
[theScrollview addSubview:theView];
}
when I start the app in my simulator, everything is shown, but if I try to scroll, nothing happens..
what do I do wrong?
Autolayout set some constraints after the view loads, so, pick your code that sets the content size in viewDidLoad and put in viewDidAppear, and your code won't be rewritten.
This worked for me.
-(void)viewDidAppear:(BOOL)animated{
[self.scrollView setContentSize:CGSizeMake(320, 1000)];
}
and sorry for my poor english.
Ensure that "Use Autolayout" is unchecked in the IB Document attributes. I had the exact same issue, setting the correct contentSize and all, but with this feature enabled, scrolling was always disabled.
UPDATE To use Autolayout, explicitly set the width and height of the scrollView's content in the viewDidAppear method, like this:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// set the scrollview to the specified size
CGRect screenRect = [[UIScreen mainScreen] bounds];
[scrollView setContentSize:CGSizeMake(screenRect.size.width, 1100)];
[scrollView setBounds:CGRectMake(0, 0, screenRect.size.width, screenRect.size.height)];
[scrollView setScrollIndicatorInsets:UIEdgeInsetsFromString(#"{0,0,0,-1.0}")];
}
Immediately change the frame of theScrollView to 320x480 and you should see scrolling.

iOS willRotateToInterfaceOrientation proper usage

I have a very simply UIViewController, and I'm trying to figure out how to use willRotateToInterfaceOrientation. my UIViewController has a very simple viewDidLoad method:
-(void)viewDidLoad {
[super viewDidLoad];
theBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 48.0f)];
theBar.tintColor = [UIColor orangeColor];
UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:#"The Title"];
item.hidesBackButton = YES;
[theBar pushNavigationItem:item animated:YES];
[item release];
[self.view addSubview:theBar];
}
So basically, I just have a UINavigationBar at the top of my controller. That's it. I implemented some methods for rotation, based on what I found online:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
-(void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration {
if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation == UIInterfaceOrientationLandscapeRight)) {
theBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, 640, 48)];
}
}
So, I launch the app in portrait mode, and then I twist in in landscape mode. And basically, theBar still stays it's normal size, and doesn't get resized. I'm sure this is a silly question, but what is the proper way to use the rotation capability? I want to make it so that it also works if the app is launched in landscape mode. What is the best way to initialize my components when the UIViewController first launches, keeping in mind that I want support for both orientations, and also keeping in mind that I want to be able to change the size of everything based on orientation changes throughout the duration of the life of the UIViewController? Thanks!
What you want to do is change the frame of your existing theBar object, and not instantiate a new one. You can do that with something like this:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation
duration:(NSTimeInterval)duration {
CGRect f = CGRectMake(0,
0,
CGRectGetWidth(self.view.frame),
CGRectGetHeight(theBar.frame);
theBar.frame = f;
}
Note that the value of self.view.frame is used, which contains values post rotation. Also note that the function I'm using here is different than yours. I haven't tested it with the function you're using, so I can't say if that'll work or not. Finally, you can avoid this altogether by just setting the autoresizingmask on theBar in viewDidLoad instead:
[theBar setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin];

iOS: navigation bar's titleView doesn't resize correctly when phone rotates

I'm writing an iPhone app that (like most apps) supports auto-rotation: You rotate your phone, and its views rotate and resize appropriately.
But I am assigning a custom view to navigationItem.titleView (the title area of the navigation bar), and I can't get that view to resize correctly when the phone rotates.
I know what you're thinking, "Just set its autoresizingMask to UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight," but it's not that simple. Of course, if I don't set my view's autoresizingMask, then my view doesn't resize; and I want it to resize.
The problem is, if I do set its autoresizingMask, then it resizes correctly as long as that view is visible; but the titleView's size gets messed up in this scenario:
Run the app, with the phone held in portrait mode. Everything looks good.
Do something that causes the app to push another view onto the navigation stack. E.g. click a table row or button that causes a call to [self.navigationController pushViewController:someOtherViewController animated:YES].
While viewing the child controller, rotate the phone to landscape.
Click the "Back" button to return to the top-level view. At this point, the title view is messed up: Although you are holding the phone in landscape mode, the title view is still sized as if you were holding it in portrait mode.
Finally, rotate the phone back to portrait mode. Now things get even worse: The title view shrinks in size (since the navigation bar got smaller), but since it was already too small, now it is much too small.
If you want to reproduce this yourself, follow these steps (this is a bit of work):
Make an app using Xcode's "Navigation-based Application" wizard.
Set it up so that the top-level table view has rows that, when you click them, push a detail view onto the navigation stack.
Include this code in both the top-level view controller and the detail view controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
Include this code in only the top-level view controller:
- (void)viewDidLoad {
[super viewDidLoad];
// Create "Back" button
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Master"
style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
// Create title view
UILabel* titleView = [[[UILabel alloc] initWithFrame:CGRectMake(0,0,500,38)] autorelease];
titleView.textAlignment = UITextAlignmentCenter;
titleView.text = #"Watch this title view";
// If I leave the following line turned on, then resizing of the title view
// messes up if I:
//
// 1. Start at the master view (which uses this title view) in portrait
// 2. Navigate to the detail view
// 3. Rotate the phone to landscape
// 4. Navigate back to the master view
// 5. Rotate the phone back to portrait
//
// On the other hand, if I remove the following line, then I get a different
// problem: The title view doesn't resize as I want it to when I:
//
// 1. Start at the master view (which uses this title view) in portrait
// 2. Rotate the phone to landscape
titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.navigationItem.titleView = titleView;
}
Finally, follow my repro steps.
So ... am I doing something wrong? Is there a way to make my titleView always resize correctly?
You should also set the contentMode of the UIImageView to get the titleView properly displayed in landscape and/or portrait mode :
imgView.contentMode=UIViewContentModeScaleAspectFit;
The whole sequence: (self is a UIViewController instance)
UIImageView* imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myCustomTitle.png"]];
imgView.autoresizingMask=UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imgView.contentMode=UIViewContentModeScaleAspectFit;
self.navigationItem.titleView = imgView;
[imgView release];
I had something similar - but it was returning (popping) to root view controller. Ultimately, I went with the following for popping:
[[self navigationController] setNavigationBarHidden:YES animated:NO];
[[self navigationController] popViewControllerAnimated:YES];
[[self navigationController] setNavigationBarHidden:NO animated:NO];
And it worked. There may have been a better way but - after all the hours I'd already spent on this issue - this was good enough for me.
I dealt with this same issue by keeping track of the customView's initial frame, then toggling between that and a scaled CGRect of the initial frame in a -setLandscape method on a UIButton subclass. I used the UIButton subclass as navigationItem.titleView and navigationItem.rightBarButtonItem.
In UIButton subclass -
- (void)setLandscape:(BOOL)value
{
isLandscape = value;
CGFloat navbarPortraitHeight = 44;
CGFloat navbarLandscapeHeight = 32;
CGRect initialFrame = // your initial frame
CGFloat scaleFactor = floorf((navbarLandscapeHeight/navbarPortraitHeight) * 100) / 100;
if (isLandscape) {
self.frame = CGRectApplyAffineTransform(initialFrame, CGAffineTransformMakeScale(scaleFactor, scaleFactor));
} else {
self.frame = initialFrame;
}
}
Then in the InterfaceOrientation delegates I invoked the -setLandscape method on the customViews to change their sizes.
In UIViewController -
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self updateNavbarButtonsToDeviceOrientation];;
}
- (void)updateNavbarButtonsToDeviceOrientation
{
ResizeButton *rightButton = (ResizeButton *)self.navigationItem.rightBarButtonItem.customView;
ResizeButton *titleView = (ResizeButton *)self.navigationItem.titleView;
if (self.interfaceOrientation == UIDeviceOrientationPortrait || self.interfaceOrientation == UIDeviceOrientationPortraitUpsideDown) {
[rightButton setLandscape:NO];
[titleView setLandscape:NO];
} else {
[rightButton setLandscape:YES];
[titleView setLandscape:YES];
}
}
(Answering my own question)
I got this working by manually keeping track of the titleView's margins (its distance from the edges of the navigtion bar) -- saving when the view disappears, and restoring when the view reappears.
The idea is, we aren't restoring the titleView to the exact size it had previously; rather, we are restoring it so that it has the same margins it had previously. That way, if the phone has rotated, the titleView will have a new, appropriate size.
Here is my code:
In my view controller's .h file:
#interface MyViewController ...
{
CGRect titleSuperviewBounds;
UIEdgeInsets titleViewMargins;
}
In my view controller's .m file:
/**
* Helper function: Given a parent view's bounds and a child view's frame,
* calculate the margins of the child view.
*/
- (UIEdgeInsets) calcMarginsFromParentBounds:(CGRect)parentBounds
childFrame:(CGRect)childFrame {
UIEdgeInsets margins;
margins.left = childFrame.origin.x;
margins.top = childFrame.origin.y;
margins.right = parentBounds.size.width -
(childFrame.origin.x + childFrame.size.width);
margins.bottom = parentBounds.size.height -
(childFrame.origin.y + childFrame.size.height);
return margins;
}
- (void)viewDidUnload {
[super viewDidUnload];
titleSuperviewBounds = CGRectZero;
titleViewMargins = UIEdgeInsetsZero;
}
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
// Keep track of bounds information, so that if the user changes the
// phone's orientation while we are in a different view, then when we
// return to this view, we can fix the titleView's size.
titleSuperviewBounds = self.navigationItem.titleView.superview.bounds;
CGRect titleViewFrame = self.navigationItem.titleView.frame;
titleViewMargins = [self calcMarginsFromParentBounds:titleSuperviewBounds
childFrame:titleViewFrame];
}
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Check for the case where the user went into a different view, then
// changed the phone's orientation, then returned to this view. In that
// case, our titleView probably has the wrong size, and we need to fix it.
if (titleSuperviewBounds.size.width > 0) {
CGRect newSuperviewBounds =
self.navigationItem.titleView.superview.bounds;
if (newSuperviewBounds.size.width > 0 &&
!CGRectEqualToRect(titleSuperviewBounds, newSuperviewBounds))
{
CGRect newFrame = UIEdgeInsetsInsetRect(newSuperviewBounds,
titleViewMargins);
newFrame.size.height =
self.navigationItem.titleView.frame.size.height;
newFrame.origin.y = floor((newSuperviewBounds.size.height -
self.navigationItem.titleView.frame.size.height) / 2);
self.navigationItem.titleView.frame = newFrame;
}
}
}
For IOS5 onwards, as this is an old question...This is how I accomplished the same issue with the title text not aligning properly.
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:2 forBarMetrics:UIBarMetricsLandscapePhone];
Tested on ios5/6 sims works fine.
This is what I did:
self.viewTitle.frame = self.navigationController.navigationBar.frame;
self.navigationItem.titleView = self.viewTitle;
The viewTitle is a view created in the xib, it takes the size of the navigationBar and after it has been added the titleView adjust the size to leave room to the back button. Rotations seem to work fine.
I had had same problem, but I seem to get workaround with following code.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UIView *urlField = self.navigationItem.leftBarButtonItem.customView;
CGRect frame = urlField.frame;
frame.size.width = 1000;
urlField.frame = frame;
}
In my case, the custom view is a UITextField, but I hope this will help you.