在 iOS8 中使用 [UIView(Geometry) _applyISEngineLayoutValues] 重新进入视图时出现问题,但在 iOS7 中则不然

2024-01-09

我正在开发一个由其他人启动的应用程序,我相信是在 iOS 5 发布时启动的。大多数 UI 都是代码生成的,不会显式使用自动布局和约束。但是,有一些(后来添加的)自包含 UI 元素,在 nib(xib) 中定义,内部使用自动布局,这些元素包含在应用程序的更高级别视图中(在代码中生成,不使用自动布局)。

一段代码生成这些自包含元素之一的合成图像,将该图像动画化,然后将该图像交换为实际的 UI 元素视图。各种这些自包含的 UI 元素(全部基于相同的基类,但具有自己的笔尖 (xib))可以传递到此例程中,按照说明显示它们。其中大多数在 iOS 7 和 iOS 8 中运行良好,可以在屏幕上显示动画。

然而,一个特定的 UI 元素(仅在 iOS8 上)可以正确显示动画,但在动画的完成部分完成后,它会重置其位置,使其中心位于 0,0。这个在 iOS 7 上运行得很好。

我比较了与该元素配合良好的元素的代码和笔尖,但在有问题的 UI 元素的创建和内部组成方面没有看到任何不同的做法。

我在 @"center" 键路径的视图中添加了一个键路径观察器,这样我就可以看到是谁导致了这种重新居中,并且它似乎在自动布局系统代码中——我的代码都不在回溯中。



#0  0x002ed826 in -[MyFundsManager observeValueForKeyPath:ofObject:change:context:] at /Users/me/Dev/MyApp/iosapp/MyApp/MyFundsManager.m:158
#1  0x24b30372 in NSKeyValueNotifyObserver ()
#2  0x24b3001e in NSKeyValueDidChange ()
#3  0x24b1c840 in -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] ()
#4  0x27463738 in -[UIView(Geometry) _applyISEngineLayoutValues] ()
#5  0x273898ee in -[UIView(Geometry) _resizeWithOldSuperviewSize:] ()
#6  0x23dff6ee in __53-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]_block_invoke ()
#7  0x23dff5ea in -[__NSArrayM enumerateObjectsWithOptions:usingBlock:] ()
#8  0x2737a54a in -[UIView(Geometry) resizeSubviewsWithOldSize:] ()
#9  0x2746389c in -[UIView(AdditionalLayoutSupport) _is_layout] ()
#10 0x2760dbd4 in -[UIView(Hierarchy) _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] ()
#11 0x27372b36 in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#12 0x26d9accc in -[CALayer layoutSublayers] ()
#13 0x26d966b4 in CA::Layer::layout_if_needed(CA::Transaction*) ()
#14 0x26d9653c in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()
#15 0x26d95f20 in CA::Context::commit_transaction(CA::Transaction*) ()
#16 0x26d95d24 in CA::Transaction::commit() ()
#17 0x2736afc4 in _afterCACommitHandler ()
#18 0x23e9e5cc in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#19 0x23e9bc8a in __CFRunLoopDoObservers ()
#20 0x23e9c092 in __CFRunLoopRun ()
#21 0x23dea620 in CFRunLoopRunSpecific ()
#22 0x23dea432 in CFRunLoopRunInMode ()
#23 0x2b1980a8 in GSEventRunModal ()
#24 0x273d4808 in UIApplicationMain ()
#25 0x0003e3fc in main at /Users/me/Dev/MyApp/iosapp/MyApp/main.m:17
  

下面的代码对传入的自包含 UI 元素进行动画处理,该元素是一个自包含视图控制器和视图,其内部组合通过笔尖和自动布局实现。

“inView”是传入的视图,应包含 UI 元素(UI 元素的父视图)。 “payPage”是自包含 UI 元素的视图控制器。

CGRect payRect = CGRectMake(windowSize.width/2 - pageSize.width/2, windowSize.height/2 - pageSize.height/2 - offset, pageSize.width, pageSize.height); UIGraphicsBeginImageContext(payPage.view.bounds.size); [[[payPage view] layer] renderInContext:UIGraphicsGetCurrentContext()]; //[[payPage view] drawViewHierarchyInRect:payPage.view.bounds afterScreenUpdates:YES];// iOS8 issues with this -- jumps and flickers UIImage *compositeImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();

UIImageView *compositeImageView = [[UIImageView alloc] initWithImage:compositeImage];

[[payPage view] setAlpha:0.0f];

UIViewController *parentVC = [self visibleVC];

_parentVC = parentVC;

UIView *inView = [(MyStandardViewController *)parentVC localView];

CGRect middleRect = CGRectZero;

if (nil == fromView)
{
    middleRect.origin = [[[UIApplication sharedApplication] keyWindow] center];
}
else
{
    middleRect.origin = [[fromView superview] convertPoint:[fromView center] toView:inView];
}
[compositeImageView setFrame:middleRect];

_blockingView = [[UIView alloc] initWithFrame:[inView frame]];
[_blockingView setAlpha:0.0f];
[_blockingView setBackgroundColor:BLOCKINGVIEWBACKGROUNDCOLOR];

[inView addSubview:_blockingView];

[inView addSubview:compositeImageView];

[UIView animateWithDuration:2.25f animations:^{

        [compositeImageView setFrame:payRect];
        [_blockingView setAlpha:1.0f];
        }
    completion:^(BOOL finished) {

        [inView addSubview:[payPage view]];
        if (nil != parentVC)
           {
             [parentVC addChildViewController:payPage];
              }

        [[payPage view] setFrame:payRect];            
        [[payPage view] setAlpha:1.0f];           
        [compositeImageView removeFromSuperview];        
        }
    ];

就我而言,我有一个“隐藏的”setTranslatesAutoresizingMaskIntoConstraints:NO在实现我错过的子视图时。消除这个问题使一切都按其应有的方式进行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 iOS8 中使用 [UIView(Geometry) _applyISEngineLayoutValues] 重新进入视图时出现问题,但在 iOS7 中则不然 的相关文章

随机推荐