如何才能获得正确尺寸的UIView?

时间:2013-01-11 23:11:00

标签: iphone ios ipad cocoa-touch uiview

问题1:

如何获得正确的UIView大小?

我正在创建一个CGRect来使用平铺图层显示一些图像。 当我创建CGRect时,我基本上需要它与我的UIView的大小完全相同。事实证明这很难...... 当我NSLog()出我的mainView.bounds.size.width或我的mainView.frame.size.width时,他们在景观中总是错的!即使我可以看到实际视图更宽,它们也总是将图像注释为纵向。扭转它们也是错误的。 在景观中将宽度设置为高度是不够的,反之亦然,我需要正确的值。

我能够让它看起来正确的唯一方法是在横向时手动输入1024宽度,这也不总是有效,因为:

问题2:

检查设备是否处于横向状态的正确方法是什么?

我一直在使用

if([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight)

但这并不总是有效。如果我在启动时将设备保持在横向模式,这是正确的,但如果我将其设置为横向,则将iPad平放,将仪表板作为横向放置,然后启动它,然后显示横向 - 但代码认为它是纵向的。 该代码根本不适用于iPad模拟器..

修改

出于某种原因,当我决定添加对横向方向的支持时,仅仅检查目标摘要页面中的横向方向是不够的,我实际上必须对我的TabBarController进行子类化并实际告知它用

旋转
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return YES;
}

我不应该这样做..对吗?如果我创建一个这样的空项目,它不需要它......我不知道为什么。

2 个答案:

答案 0 :(得分:1)

问题1: 是的,没错。 :)

问题2: 我刚回到家,检查了自己的代码。我用:

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

检查当前界面的方向。然后,你可以使用类似的东西:

if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    // Do something
} else if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation)){
    // Do something else
}

HOWEVER 如果你正确处理轮换事件,你真的不需要这样做。

当我需要根据方向调整代码中的UI元素位置时,这是我处理旋转的典型方法:

#pragma mark - View rotation methods

// Maintain pre-iOS 6 support:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

// Make sure that our subviews get moved on launch:
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    [self moveSubviewsToOrientation:orientation duration:0.0];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    [self moveSubviewsToOrientation:toInterfaceOrientation duration:duration];
}

// Animate the movements
- (void)moveSubviewsToOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration
{
    [UIView animateWithDuration:duration
                     animations:^{
                         [self.tableView reloadData];
                         if (UIInterfaceOrientationIsPortrait(orientation))
                         {
                             [self moveSubviewsToPortrait];
                         }
                         else
                         {
                             [self moveSubviewsToLandscape];
                         }
                     }
                     completion:NULL];
}

- (void)moveSubviewsToPortrait
{
    // Set the frames/etc for portrait presentation
    self.logoImageView.frame = CGRectMake(229.0, 21.0, 309.0, 55.0);
}

- (void)moveSubviewsToLandscape
{
    // Set the frames/etc for landscape presentation
    self.logoImageView.frame = CGRectMake(88.0, 21.0, 309.0, 55.0);
}

我还将moveSubviewsToOrientation放入viewWillAppear以使其旋转

答案 1 :(得分:1)

我有点挣扎,这是我发现的一些事实:

1-当设备面朝上或朝下时,设备会在面朝上或朝下之前恢复到最后一个方向,因为这两个方向并不一定能告诉您设备是纵向还是横向。例如,如果您处于横向状态,然后将设备面朝上放置,然后启动应用程序,它将以横向方向启动。

2-调用viewDidLoad时,尚未设置边界,因此您需要在viewWillAppear或viewDidLayoutSubviews中放置与方向相关的任何调用。

3-如果由于某些奇怪的原因,您需要在viewDidLoad之前使用边界,或者可能在模型中执行某些操作,我发现放置与方向相关的设置的最佳方法是信任状态栏,例如,您可以如下调用。

if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))

PS:关于您添加的问题,请参阅: https://developer.apple.com/library/ios/#qa/qa2010/qa1688.html

你很可能是最后2发子弹中的一个。我之前遇到过这个问题,并且坦率地说它最容易实现:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;

对于所有VC而言,只是为了安全起见,特别是行为已从iOS5更改为iOS6。

http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/RespondingtoDeviceOrientationChanges/RespondingtoDeviceOrientationChanges.html#//apple_ref/doc/uid/TP40007457-CH7-SW1

希望这有帮助