当前位置: 首页 > 知识库问答 >
问题:

在iOS8下使用CGaffineTransform旋转时,UIView不会调整大小

孙梓
2023-03-14

我有一个UIViewController,当设备旋转时,它只旋转其中的一些子视图。这在iOS7下运行良好,但在iOS8下会中断。UIView的边界似乎是由iOS8下的变换调整的。这是出乎意料的。

这里有一些代码:

@interface VVViewController ()
@property (weak, nonatomic) IBOutlet UIView *pinnedControls;
@property (nonatomic, strong) NSMutableArray *pinnedViews;

@end

@implementation VVViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.pinnedViews = [NSMutableArray array];
    [self.pinnedViews addObject:self.pinnedControls];
}

-(void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    [UIViewController rotatePinnedViews:self.pinnedViews forOrientation:self.interfaceOrientation];
}

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

    if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation) && UIInterfaceOrientationIsLandscape(self.interfaceOrientation))  {
        [UIViewController rotatePinnedViews:self.pinnedViews forOrientation:toInterfaceOrientation];
    }
}

@end

我们在UIViewController上创建了一个类别来处理此行为。以下是相关代码:

@implementation UIViewController (VVSupport)

+ (void)rotatePinnedViews:(NSArray *)views forOrientation:(UIInterfaceOrientation)orientation {
    const CGAffineTransform t1 = [UIViewController pinnedViewTansformForOrientation:orientation counter:YES];
    const CGAffineTransform t2 = [UIViewController pinnedViewTansformForOrientation:orientation counter:NO];
    [views enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) {
        // Rotate the view controller
        view.transform = t1;
        [view.subviews enumerateObjectsUsingBlock:^(UIView *counterView, NSUInteger idx, BOOL *stop) {
            // Counter-rotate the controlsUIin the view controller
            counterView.transform = t2;
        }];
    }];
}

+ (CGAffineTransform)pinnedViewTansformForOrientation:(UIInterfaceOrientation)orientation counter:(BOOL)counter {
    CGAffineTransform t;
    switch ( orientation ) {
        case UIInterfaceOrientationPortrait:
        case UIInterfaceOrientationPortraitUpsideDown:
            t = CGAffineTransformIdentity;
            break;

        case UIInterfaceOrientationLandscapeLeft:
            t = CGAffineTransformMakeRotation(counter ? M_PI_2 : -M_PI_2);
            break;

        case UIInterfaceOrientationLandscapeRight:
            t = CGAffineTransformMakeRotation(counter ? -M_PI_2 : M_PI_2);
            break;
    }

    return t;
}

@end

以下是笔尖的外观:

nib中名为pinned的UIView是pinnedControls的IBOutlet:

当我在iOS7或iOS8下竖屏运行时,我得到了这个:

我在横向模式下看到了iOS7下的预期结果:

但在iOS8(GM)下,我没有这种行为。我看到的是:

请注意,带有文本“Pinned Label”的UILabel的中心与Pinned UIView的底部保持距离,该视图的大小没有改变以适应旋转。该UIView的所有边都固定在超级视图的顶部、左侧、底部和右侧。

在我看来,在iOS8下,转换属性与自动布局的交互方式不同。我在这里有点困惑。我知道我不能依赖框架。我可能只是开始手动设置边界,但这似乎是错误的做法,本质上是围绕自动布局进行最终运行。

共有3个答案

申屠浩歌
2023-03-14

在ios8中,uiview控制器需要根据设备方向使用uitrait集合调整大小。否则,当您尝试旋转它时,您会得到竖屏的uiview,而手机则是横向的。所以正确的步骤是旋转并覆盖uitrait集合

编辑:我用以下代码重写uitraitcollection*hortracit=[uitraitcollection-traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];UITraitCollection*verTrait=[UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];UITraitCollection*finalTrait=[UITraitCollection traitCollectionWithTraitsFromCollections:@[Hortracit,verTrait]];[self.parentViewController setOverrideTraitCollection:finalTrait for ChildViewController:self]

不幸的是,如果我尝试修改的uiviewcontroller没有parentviewcontroller,则无法正常工作:'(

韦业
2023-03-14

这与其说是修复,不如说是解决问题,所以它可能不会对类似情况下的每个人都有帮助。我的问题是,在应用转换后,外部“固定”视图再次被调整大小。

我的解决方案是将固定视图的约束更改为垂直居中、水平居中,并且宽度和高度等于常量。

然后,在viewDidLoad中,我将固定视图框架的高度和宽度设置为主屏幕的高度。这使得视图呈方形,所以我不在乎它是否得到额外的旋转。

卫嘉泽
2023-03-14

所以这让我在过去的几天里发疯了,我可以通过更改动画块中setTransform调用的时间来修复

在进行横向时,我将在设置新帧后设置变换。在进行纵向绘制时,我会在设置新帧之前设置变换。所有这些都是在“animateWithDuration…”的动画块中进行的方法

我不确定它是否会直接帮助您处理代码,但它可能会激发一些灵感来解决它,因为我们肯定有类似的问题

 类似资料:
  • 当使用sharp image resize库https://github.com/lovell/sharp for Node.js时,图像将被旋转。 我没有写.rotate()的代码,那么为什么要旋转它,我怎样才能阻止它旋转呢? 我使用的是AWS提供的无服务器图像大小调整示例:https://github.com/awslabs/serverless-image-resizing。如果缩略图不存在

  • 本文档概述了您可以用来调整图像的裁剪、旋转和画布大小的各种方法。 使用裁剪命令裁剪图像 使用选区工具来选择要保留的图像部分。 选取“图像”>“裁剪”。 使用裁切命令裁剪图像 “裁切”命令通过移去不需要的图像数据来裁剪图像,其所用的方式与“裁剪”命令所用的方式不同。可以通过裁切周围的透明像素或指定颜色的背景像素来裁剪图像。 选取“图像”>“裁切”。 在“裁切”对话框中选择选项: “透明像素”修整掉图

  • 问题内容: 我正在努力围绕其中心绘制旋转的位图,并在不调整位图大小的情况下进行旋转。我正在通过游戏线程将所有子画面绘制到屏幕上,因此我正在寻找一种包含原始位图而不是画布的解决方案。 提前致谢。 到目前为止,这是我的代码,它围绕其中心旋转一个位图,但对其进行了调整。 更新: 我注意到这并不像听起来那么容易。我的旋转代码不是问题。位图旋转,但是dst rect也必须根据旋转角度增加/减少,否则bima

  • 我从供应商那里收到单页pdf文件的邮资标签。这些标签可以贴在A5纸上,但它们在A4纸上是纵向的,也是纵向的。我希望能够在A4纸上打印两个这样的标签,以减少浪费。 这可以通过旋转页面内容而不旋转页面本身来实现。或者通过交换内容的高度和宽度来调整页面的大小。我知道这两种情况都会导致内容丢失,但这对于我的用例来说不是问题。理想情况下,我希望命令行应用程序既可以在Linux机器上运行,也可以在Window

  • 已经建立了一个小的测试SWING应用程序,有三个面板。一个主JPanel,包含两个较小的JPanel。一个在左边(板面板),另一个在右边(侧板)。通过调用min、preferred和max size方法,两个内部面板都被设置为请求的特定大小。右面板中的一个按钮将父JFrame设置为not re-sizable。在父帧设置为不可调整大小之前,一切看起来都很好,这会导致(?!)调整框架和主面板的大小,

  • 问题内容: 一旦我在代码中使用了渐变,在调整大小时就不会完成重新绘制,而在调整大小时 会得到类似的信息(已调整大小的黑色矩形,请参见下面的链接中的图像)。当我停止调整大小时,一切都会 再次绘制,但只有那时。 如果我不使用,;我会快速重画 http://gui-builder.com/C41142775162.rar 我尝试调整大小,尝试拖动鼠标时却 什么也没有。 这是一些SSCCE(对不起,我之前