【问题标题】:Wrong positioning after orientation change on iPad在 iPad 上更改方向后定位错误
【发布时间】:2011-01-14 14:21:49
【问题描述】:

在更改我的 iPadd 应用程序的方向时遇到一些问题。
我编写了一个函数来布置我的子视图,以便在视图出现或旋转时调用它。
该函数在由“viewWillAppear”函数调用时可以完美运行。但是当“willAnimateRotationToInterfaceOrientation”函数调用我的布局函数(“setPositionsForOrientation”)时,我面临以下问题:

  • 从纵向更改为横向时,左侧有 128 像素的偏移量
  • 从横向更改为纵向时,左侧有一个负偏移

我的印象是,不知何故新的框架属性没有正确处理,因为我的 UIScrollViews 也应该调整大小,但他们没有这样做。

这是我写的代码:

- (void)viewWillAppear:(BOOL)animated{
 [self setPositionsForOrientation:self.interfaceOrientation];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 return YES;
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)newInterfaceOrientation duration:(NSTimeInterval)duration {
 [self setPositionsForOrientation:newInterfaceOrientation];
}

- (void)setPositionsForOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Position the UI elements for landscape mode
 if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
  self.view.frame = CGRectMake(0, 0, 1024, 748);
  self.menubarImage.frame = CGRectMake(0, 0, 1024, 121);
  self.backgroundImage.frame = CGRectMake(0, 0, 1024, 748);
  self.mainCategories.frame = CGRectMake(6, 6, 1012, 55);
  self.subCategories.frame = CGRectMake(58, 79, 960, 30);
  self.moviesContainer.frame = CGRectMake(6, 204, 1012, 456);
  self.searchButton.frame = CGRectMake(935, 709, 80, 30);
 }
 // Position the UI elements for portrait mode
 else {
  self.view.frame = CGRectMake(0, 0, 768, 1004);
  self.menubarImage.frame = CGRectMake(0, 256, 768, 121);
  self.toolbarImage.frame = CGRectMake(0, 924, 768, 80);
  self.backgroundImage.frame = CGRectMake(0, 256, 768, 748);
  self.mainCategories.frame = CGRectMake(6, 262, 756, 55);
  self.subCategories.frame = CGRectMake(58, 335, 704, 30);
  self.moviesContainer.frame = CGRectMake(6, 460, 756, 456);
  self.searchButton.frame = CGRectMake(680, 963, 80, 30);
 }
}

这里有一些图片来说明我的问题..

IB 中的布局(所有子视图的 contentMode 设置为 Top-Left)

http://www.abload.de/image.php?img=interfacebuilderl9ey.png 

人像模式显示正确/奇怪

http://www.abload.de/image.php?img=portrait_oklxf1.png
http://www.abload.de/image.php?img=portrait_failma8y.png

横向模式显示正确/奇怪

http://www.abload.de/image.php?img=landscape_ok4z2l.png
http://www.abload.de/image.php?img=landscape_failvzuy.png

我做错了什么,更重要的是,我该如何解决?
我发现this 帖子描述了通常的方式,但我不明白如何覆盖我的视图“layoutSubviews”方法,因为视图只是我的 UIViewController 的一个属性..

【问题讨论】:

    标签: objective-c animation orientation landscape portrait


    【解决方案1】:

    如果你想创建自己的 UIView 子类并将其设置为 UIViewController 以便实现 layoutSubviews 方法,实际上非常简单!

    UIViewController 不会创建期望用户设置视图的视图,但是当使用 Interface BUilder 时,已经为我们设置了 UIView。

    要更改视图,请执行以下操作:

    • 创建您的子类,在这里我假设它称为 MyView,并将您的所有 UI 内容(工具栏、按钮等)放在那里。
    • 在 IB 中打开您的视图控制器文件(*.xib)
    • 选择视图(我们正在更改的视图)
    • 转到身份检查器(或按 Cmd+4)
    • 在类标识字段中输入“MyView”

    由于您将所有 UI 元素都作为 ivar 放在视图中,因此您不能再从 UIViewController 访问它们,对吧?因此,请确保您有正确的访问器/属性和方法来处理来自 UIViewController 的视图(及其 ivars)。 ;)

    祝你好运;)

    编辑:2011/01/17

    当您在控制器中并执行 [self.view xyz] 时,您会收到警告吗? 那是因为 UIViewController 的视图被声明为 UIView 对象。你将 UIView 子类化并在 IB 中设置它。因此,每次访问视图时都必须强制转换它,否则编译器会认为它仍然是正常的 UIView,它没有您在 MyView 中声明的方法。这样做:

    [(MyView *)self.view xyz]; //and for that don't forget to #import "MyView.h"
    

    这应该可行。但是我不明白为什么然后得到:“属性'view'类型与超类'UIViewController'属性类型不匹配”首先尝试我刚才说的;)你确定你将MyView声明为:

    @interface MyView: UIView{
    ...
    }
    @property (...) XYZ *xyz;
    ...
    @end
    

    【讨论】:

    • 我做了你告诉我的一切,并将所有 ivars 和属性移动到新的视图类。但是,对于所有属性,我收到错误“请求成员 不是结构或联合”。如果我用我的新类重新声明视图控制器中的视图属性,则此错误消失,但随后我收到警告“属性'视图'类型与超类'UIViewController'属性类型不匹配”并且应用程序在视图控制器崩溃时崩溃被陈列。 :(
    • 谢谢,应用程序现在可以编译并且可以运行,但是定位错误的问题仍然存在:(
    【解决方案2】:

    我在 .m 文件的 MyView 类中添加了以下代码,它帮助我摆脱了痛苦:

    - (void)awakeFromNib
    {
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多