这种情况开始发生的原因是,任何作为a属性UIView
值的实例有时都会收到一条消息,将其视图调整为其父视图的大小。UIViewController
view
具体来说,viewDidMoveToWindow:shouldAppearOrDisappear:
当视图控制器添加到窗口时,将调用未记录的方法view
,就像在此实例中启动应用程序时发生的那样。这时,如果视图控制器的view
实例是主窗口的大小或更大,它会被调整为其父视图的大小。
原始代码采用从 .xib 加载的两个视图,并将它们的大小调整为 768 * 1024,即窗口大小。这发生在窗口上调用之前 -makeKeyAndVisible
,最终触发调整大小。我在应用程序委托中使用 KVO 来观察框架的大小调整;这是调整大小时的堆栈跟踪:
* thread #1: tid = 0x1f03, 0x000030f9 scroller`-[ViewController observeValueForKeyPath:ofObject:change:context:] + 105 at ViewController.m:71, stop reason = breakpoint 1.1
frame #0: 0x000030f9 scroller`-[ViewController observeValueForKeyPath:ofObject:change:context:] + 105 at ViewController.m:71
frame #1: 0x0093ad91 Foundation`NSKeyValueNotifyObserver + 345
frame #2: 0x0093a895 Foundation`NSKeyValueDidChange + 438
frame #3: 0x0092033e Foundation`-[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 131
frame #4: 0x009cdcb4 Foundation`_NSSetRectValueAndNotify + 187
frame #5: 0x000e1786 UIKit`-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:] + 657
frame #6: 0x0005310c UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 1040
frame #7: 0x00052edb UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 479
frame #8: 0x0005d5ab UIKit`-[UIScrollView _didMoveFromWindow:toWindow:] + 65
frame #9: 0x00052edb UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 479
frame #10: 0x0004f692 UIKit`-[UIView(Hierarchy) _postMovedFromSuperview:] + 158
frame #11: 0x0005446f UIKit`-[UIView(Internal) _addSubview:positioned:relativeTo:] + 1633
frame #12: 0x0004e14b UIKit`-[UIView(Hierarchy) addSubview:] + 56
frame #13: 0x0003d550 UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 380
frame #14: 0x0003d670 UIKit`-[UIWindow _setHidden:forced:] + 280
frame #15: 0x0003d836 UIKit`-[UIWindow _orderFrontWithoutMakingKey] + 49
frame #16: 0x0004472a UIKit`-[UIWindow makeKeyAndVisible] + 35
frame #17: 0x00002575 scroller`-[AppDelegate application:didFinishLaunchingWithOptions:] + 661 at AppDelegate.m:21
frame #18: 0x00015386 UIKit`-[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1292
frame #19: 0x00016274 UIKit`-[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 524
frame #20: 0x00025183 UIKit`-[UIApplication handleEvent:withNewEvent:] + 1027
frame #21: 0x00025c38 UIKit`-[UIApplication sendEvent:] + 68
frame #22: 0x00019634 UIKit`_UIApplicationHandleEvent + 8196
frame #23: 0x0139eef5 GraphicsServices`PurpleEventCallback + 1274
frame #24: 0x01488195 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
frame #25: 0x013ecff2 CoreFoundation`__CFRunLoopDoSource1 + 146
frame #26: 0x013eb8da CoreFoundation`__CFRunLoopRun + 2218
frame #27: 0x013ead84 CoreFoundation`CFRunLoopRunSpecific + 212
frame #28: 0x013eac9b CoreFoundation`CFRunLoopRunInMode + 123
frame #29: 0x00015c65 UIKit`-[UIApplication _run] + 576
frame #30: 0x00017626 UIKit`UIApplicationMain + 1163
frame #31: 0x000022ad scroller`main + 141 at main.m:16
UIViewController
我们可以通过实例化视图并同时将其添加到滚动视图来验证是否发生这种情况,因为内容视图是的视图实例。ViewController
我在's实现的末尾添加了以下代码viewDidLoad
:
CGRect frame3 = frame2;
frame3.origin.x = 768.0f * 2.0f;
UIView *thirdView = [[UIView alloc] initWithFrame:frame3];
[thirdView setBackgroundColor:[UIColor redColor]];
[self.scrollView addSubview:thirdView];
以及将分配内容大小的行更改为:
[self scrollView].contentSize = CGSizeMake(768 * 3, 1024);
此视图在期间未设置其框架,makeKeyAndVisible
并且位于正确的位置。
要解决此问题,我建议在窗口-makeKeyAndVisible
调用后设置视图层次结构,可能在 viewWillAppear 中(不确定是否会出现相同的问题)或通过其他方式构建代码以延迟滚动的布局看法。或者,稍后重新设置框架以明确撤消此错误。
我希望这有助于解释正在发生的事情,并且我提供的证据清晰可信;似乎您已经针对您的特定情况进行了修复,但希望这个答案可以作为框架不当行为的通用解决方案,当UIViewController
他们的视图布局在滚动视图中时。