【问题标题】:UITapGestureRecognizer not working in first tabUITapGestureRecognizer 在第一个选项卡中不起作用
【发布时间】:2014-02-14 14:42:21
【问题描述】:

这太奇怪了,我创建了一个新项目来测试我是否要疯了。

你可以在这里看到项目https://github.com/ojfoggin/TapTest

我创建了一个以UITabBarController 作为初始视图的项目。

第一个控制器选项卡有两个 UIimageViews。每个图像视图上都有一个 UItapGestureRecognizer,其操作仅记录“Tap 1”或“Tap 2”。

如果不使用 TabBarController,那么一切正常。但是,如果使用 TabBarController,则只有第一个点击识别器有效,第二个无效。

但是,如果您切换到不同的选项卡然后再返回,那么两个识别器都会工作?!?!?

另外,我尝试在代码中添加 Tao 手势识别器,结果完全相同。

谁能解释为什么会发生这种情况以及如何解决它?

【问题讨论】:

  • 它工作正常,但仅适用于 320 点宽。屏幕以某种方式旋转,但不是事件处理程序或其他东西。
  • @Desdenova 这也是我所看到的。很奇怪,看看这个应用程序是多么的基本......

标签: ios objective-c uitabbarcontroller uitapgesturerecognizer


【解决方案1】:

TL;DR

将您的故事板文件作为源代码 (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"/>

将解决问题。

【讨论】:

    【解决方案2】:

    我认为这来自您的应用更改方向。如果您启动应用程序并点击第二个 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'答案,因为它解决了你的问题;]

    【讨论】:

    • po on window recursiveDescription 非常清楚地表明了这一点。问题是为什么...
    • 好吧,我认为我的解决方案实际上解决了问题,而不是仅仅在代码中解决问题。
    【解决方案3】:

    @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 中,frame 是 320,568,但是当你去第二个 view 回来时,frame 被正确设置为 568,271。因此,解决方案是在将视图控制器添加到 tabbarcontroller 时正确设置框架

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      • 2015-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多