我正在编写一个iPhone应用程序(与大多数应用程序一样)支持自动旋转:旋转手机,其视图可以旋转并适当调整大小。
但是我将自定义视图分配给navigationItem.titleView
(导航栏的标题区域),当手机旋转时,我无法正确调整视图大小。
我知道你在想什么,“只需将autoresizingMask
设置为UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
,”但事情并非那么简单。当然,如果我没有设置我的视图autoresizingMask
,那么我的视图不会调整大小;我希望它能够调整大小。
问题是,如果我做设置其autoresizingMask
,那么只要该视图可见,它就会正确调整大小;但是在这种情况下titleView
的大小搞砸了:
[self.navigationController pushViewController:someOtherViewController animated:YES]
的表格行或按钮。如果您想自己重现,请按照以下步骤操作(这有点工作):
在顶级视图控制器和详细视图控制器中包含此代码:
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
仅在顶级视图控制器中包含此代码:
- (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;
}
最后,按照我的重复步骤进行操作。
所以...我做错了什么?有没有办法让我的titleView始终正确调整大小?
答案 0 :(得分:7)
您还应该设置contentMode
的{{1}},以便在横向和/或纵向模式下正确显示UIImageView
:
titleView
整个序列:( self是imgView.contentMode=UIViewContentModeScaleAspectFit;
实例)
UIViewController
答案 1 :(得分:4)
我有类似的东西 - 但它正在返回(弹出)到根视图控制器。最后,我选择以下内容进行弹出:
[[self navigationController] setNavigationBarHidden:YES animated:NO];
[[self navigationController] popViewControllerAnimated:YES];
[[self navigationController] setNavigationBarHidden:NO animated:NO];
它有效。可能有更好的方法,但是 - 经过我已经花在这个问题上的所有时间 - 这对我来说已经足够了。
答案 2 :(得分:3)
我通过跟踪customView的初始帧来处理同样的问题,然后在UIButton子类的-setLandscape方法中切换它和初始帧的缩放CGRect。我使用UIButton子类作为navigationItem.titleView和navigationItem.rightBarButtonItem。
在UIButton子类中 -
- (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;
}
}
然后在InterfaceOrientation委托中,我在customViews上调用了-setLandscape方法来改变它们的大小。
在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];
}
}
答案 3 :(得分:2)
(回答我自己的问题)
我通过手动跟踪titleView的边距(它与导航栏边缘的距离)来实现这一点 - 在视图消失时保存,并在视图重新出现时恢复。
我们的想法是,我们不会将titleView恢复到之前的确切大小;相反,我们正在恢复它,以便它具有与之前相同的边距。这样,如果手机已旋转,则titleView将具有新的适当大小。
这是我的代码:
在我的视图控制器的.h文件中:
@interface MyViewController ...
{
CGRect titleSuperviewBounds;
UIEdgeInsets titleViewMargins;
}
在我的视图控制器的.m文件中:
/**
* 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;
}
}
}
答案 4 :(得分:2)
对于IOS5以后,因为这是一个老问题......这就是我如何完成标题文本未正确对齐的相同问题。
[[UINavigationBar appearance] setTitleVerticalPositionAdjustment:2 forBarMetrics:UIBarMetricsLandscapePhone];
在ios5 / 6 sims上测试工作正常。
答案 5 :(得分:1)
这就是我所做的:
self.viewTitle.frame = self.navigationController.navigationBar.frame;
self.navigationItem.titleView = self.viewTitle;
viewTitle是在xib中创建的视图,它采用navigationBar的大小,在添加后,titleView调整大小以留出空间到后退按钮。轮换似乎工作正常。
答案 6 :(得分:0)
我遇到了同样的问题,但我似乎得到了以下代码的解决方法。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UIView *urlField = self.navigationItem.leftBarButtonItem.customView;
CGRect frame = urlField.frame;
frame.size.width = 1000;
urlField.frame = frame;
}
在我的情况下,自定义视图是一个UITextField,但我希望这对你有帮助。