这太离奇了,我创建了一个新项目,以测试我是否疯了。
您可以在此处查看项目https://github.com/ojfoggin/TapTest
我创建了一个项目UITabBarController
作为初始视图。
第一个控制器选项卡有两个UIimageViews。每个图像视图上都有一个UItapGestureRecognizer,其操作只记录“Tap 1”或“Tap 2”。
如果没有使用TabBarController,那么一切正常。但是,如果使用TabBarController,那么只有第一个点击识别器工作,第二个不能。
但是,如果您切换另一个标签然后再返回,那么两个识别器都能正常工作吗?!?!?
另外,我尝试在代码中添加Tao手势识别器,并且完全相同。
任何人都可以解释为什么会发生这种情况以及如何解决这个问题吗?
答案 0 :(得分:2)
<强> TL; DR 强>
将您的storyboard文件作为源代码(xml)打开并替换
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
与
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES/>
对于带有图像的视图控制器。
<强>解释强>
使用常见的调试工具很容易找到问题:
(lldb) po [[[[UIApplication sharedApplication] delegate] window] recursiveDescription]
显示
<UIWindow: 0x8c6a140; frame = (0 0; 320 480); autoresize = W+H; gestureRecognizers = <NSArray: 0x8c6a820>; layer = <UIWindowLayer: 0x8c66db0>>
| <UILayoutContainerView: 0x8c6a320; frame = (0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x8c62350>>
| | <UITransitionView: 0x8c6a880; frame = (0 0; 480 320); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x8c50240>>
| | | <UIViewControllerWrapperView: 0x8c6cd70; frame = (0 0; 320 480); autoresize = RM+BM; layer = <CALayer: 0x8c6c840>>
| | | | <UIView: 0x8c51070; frame = (0 0; 480 271); clipsToBounds = YES; autoresize = RM+BM; autoresizesSubviews = NO; layer = <CALayer: 0x8c51d80>>
| | | | | <UIImageView: 0x8c6bdc0; frame = (20 0; 219 160); autoresize = W+H; gestureRecognizers = <NSArray: 0x8c65180>; layer = <CALayer: 0x8c4c930>>
| | | | | <UIImageView: 0x8c6a780; frame = (247 0; 219 160); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x8c62a70>; layer = <CALayer: 0x8c6a9a0>>
| | | | | <_UILayoutGuide: 0x8c6c340; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x8c51110>>
| | | | | <_UILayoutGuide: 0x8c6c760; frame = (0 271; 0 0); hidden = YES; layer = <CALayer: 0x8c6c7d0>>
| | <UITabBar: 0x8c64180; frame = (0 271; 480 49); autoresize = W+TM; layer = <CALayer: 0x8c642a0>>
| | | <_UITabBarBackgroundView: 0x8a48e50; frame = (0 0; 480 49); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x8a48f40>>
| | | <UITabBarButton: 0x8c64980; frame = (2 1; 236 48); opaque = NO; layer = <CALayer: 0x8c684c0>>
| | | | <UITabBarButtonLabel: 0x8c64dd0; frame = (108 35; 21 12); text = 'Item'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8c64ef0>>
| | | <UITabBarButton: 0x8c69d90; frame = (242 1; 236 48); opaque = NO; layer = <CALayer: 0x8c6a250>>
| | | | <UITabBarButtonLabel: 0x8c69e70; frame = (108 35; 21 12); text = 'Item'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8c68c20>>
| | | <UIImageView: 0x8a49240; frame = (0 -0.5; 480 0.5); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x8a492d0>>
其中重要的部分是:
<UILayoutContainerView: 0x8c6a320; frame = (0 0; 320 480); autoresize = W+H;
| | <UITransitionView: 0x8c6a880; frame = (0 0; 480 320);autoresize = W+H
| | | <UIViewControllerWrapperView: 0x8c6cd70; frame = (0 0; 320 480); autoresize = RM+BM;
| | | | <UIView: 0x8c51070; frame = (0 0; 480 271); autoresize = RM+BM
请注意,UIViewControllerWrapperView
的大小不合适,因为其自动调整大小不是W+H
而是RM+BM
。然而,根本原因是UIView
的自动调整掩码,因为动态生成UIViewControllerWrapperView
并且仅复制掩码。
如果您检查故事板的源代码,您将看到以下行:
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
对于第一个视图控制器中的视图。 用
替换它<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
将解决问题。
答案 1 :(得分:1)
我认为这来自您的应用更改方向。如果您启动应用程序并点击第二个UIImageView的左侧(大约是图像的前三分之一),它会正确记录“Tap 2”。我认为发生的事情是你的应用程序以纵向方式启动,切换到横向,并且会混淆你的手势识别器的动作框架。当您离开并返回选项卡时,应用程序已处于横向状态,因此框架会正确更新。
解决方案:没有一个线索。我只处理肖像应用程序,所以我真的不知道这个方向会发生什么。话虽如此,问题的根源可能与我所说的完全不同。但我想说这是值得研究的。
编辑:
我在主视图中记录了轻击手势x位置:
NSLog(@"%f", [((UITapGestureRecognizer*)sender) locationInView:self.view].x);
识别手势的最大x位置似乎是...... 320,这是肖像应用的宽度。这似乎证实了我对你的观点有所取向的看法......
编辑2:解决方案!
我找到了这个帖子:Landscape tab bar。
问题出现在横向模式下UITabBarController
。只需在viewDidLoad
中添加以下内容:
self.view.autoresizesSubviews = YES;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
我测试过它现在工作正常。请记住在解决问题时提出Josh Adams'答案;]
答案 2 :(得分:1)
@Desdenova:rdurand是绝对正确的。我确实在视图中放了一些日志语句,加载和视图会出现,这就是它的样子。
2014-02-14 09:04:19.167 TapTest[3395:60b] The frame is {{0, 0}, {320, 568}}
2014-02-14 09:04:19.174 TapTest[3395:60b] The frame in viewwillappear is {{0, 0}, {320, 519}}
2014-02-14 09:04:27.814 TapTest[3395:60b] The frame in viewwillappear is {{0, 0}, {568, 271}}
第一次在viewDidload和viewwillappear中,帧是320,568,但是当你转到第二个视图并返回时,框架设置正确568,271。所以解决方案是将视图控制器添加到tabbarcontroller
时设置框架