8

我有一个 UIButton 的问题,它在 iOS6 中运行良好,但在 iOS7 中直到某个点都无法响应触摸事件。为了澄清,请参见下图:

ios7_button_issue

失败的按钮是 UIView 中的“全部放弃”按钮。(请注意,此按钮只是暂时禁用,这不是问题。我只是没有启用该按钮的最新测试的屏幕截图“)

此按钮忽略所有触摸,除非第一次按下 UITableViewCell 中的“放弃”或“重试”按钮。(这确实会导致视图控制器重新加载,从而触发像 ViewDidLoad 这样的生命周期方法再次被调用。)按下表格视图单元格中的“放弃”或“重试”按钮后,“放弃所有”按钮开始正常运行。

视图和“全部放弃”按钮是在控制器的 XIB 文件上构建的,而不是在代码中。这仅在 iOS7 上失败,并在触摸 taleview 单元格按钮后立即开始工作。

有人有想法么?

谢谢!

4

10 回答 10

17

我昨晚找到了解决方案。好的,我将上面的表格视图和 UIView 元素放到了一个目标框架上。

我不是 100% 确定,但似乎在 iOS6 中,按钮对事件的响应与放置位置无关。出于某种原因,在 iOS7 中,当按钮位于它应该在的框架之外时,它会忽略触摸事件,即使它确实被显示了。

我通过将视图的框架定位在正确的位置解决了这个问题,因此它覆盖了按钮。

如果我能找到有关此的任何文档,我将在此处发布。

谢谢!

于 2013-10-01T06:59:49.510 回答
7

我刚刚面临这个问题。根据@Guntis Treulands 的建议,我决定检查如果我hitTest:withEvent:在自定义标题视图中覆盖方法会发生什么。此方法忽略隐藏、禁用用户交互或 alpha 级别小于 0.01 的视图对象。此方法在确定命中时不考虑视图的内容。因此,即使指定的点在视图内容的透明部分中,仍然可以返回视图,现在,在它被覆盖之后,接收到边界之外的触摸。它对我有用。希望它可以帮助你,伙计们。

迅速

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    guard !isHidden, alpha > 0 else {
      return super.hitTest(point, with: event)
    }
    
    for subview in subviews {
      let subpoint = subview.convert(point, from: self)
      let result = subview.hitTest(subpoint, with: event)
      if result != nil {
        return result
      }
    }
    return super.hitTest(point, with: event)
}

Objective-C

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (!self.clipsToBounds && !self.hidden && self.alpha > 0) {
        for (UIView *subview in self.subviews.reverseObjectEnumerator) {
            CGPoint subPoint = [subview convertPoint:point fromView:self];
            UIView *result = [subview hitTest:subPoint withEvent:event];
            if (result != nil) {
                return result;
            }
        }
    }
    // use this to pass the 'touch' onward in case no subviews trigger the touch
    return [super hitTest:point withEvent:event];
}
于 2014-03-04T17:10:21.557 回答
2

就像一个替代答案 - 实际上对我来说,这从来没有奏效(如果 uibutton 在它的父视图之外,那么它将不会收到触摸。) - 但在某些情况下,它需要让按钮在它的边界之外。

出于这个原因,有一个可以被覆盖的 hittest 函数——简单地检查父视图的所有子视图以找到放置在父视图边界之外的 uibutton。(然后,您将检查每个子视图,如果它是 uibutton 类型,并且触摸的坐标是否在 uibuttons 框架内。

默认情况下,hittest 函数会跳过检查视图,即外部边界。

Hittest 示例:https ://stackoverflow.com/questions/17246488/best-way-to-perform-the-hit-test-objective-c 。

于 2013-10-11T09:08:45.570 回答
1

我遇到了同样的问题 - 按钮在 iOS6 上确实有效,但在 iOS7 上无效,问题出在UIView我要添加的容器上UIButtons,我向容器添加了约束UIView,它开始工作。我必须在我的案例中添加的代码:

[superView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:    [_controllersView]-|" options:0 metrics:nil views:views]];
[superView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_controllersView(70)]" options:0 metrics:nil views:views]];
[superView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_controllersView]|" options:0 metrics:nil views:views]];
于 2013-12-03T16:24:30.340 回答
1

这很奇怪,但我正在为 iOS 7 开发一个新应用程序,并且设置[cell.contentView setUserInteractionEnabled: YES];实际上对我有用。

于 2013-11-07T19:24:06.557 回答
1

不确定这是否是相同的情况,但它可能是相关的:

当 UIButton 位于具有未将 delaysTouchesEnded 设置为 NO(默认为 YES)的 UIGestureRecognizer 的视图中时,该按钮将不再在 iOS 7 中获得 TouchUpInside 事件。它在 iOS 6 中确实获得了 TouchUpInside 事件。

如果可能,将 UIGestureRecognizer 的 delaysTouchesEnded 属性设置为 NO 以解决问题。

于 2013-10-11T08:52:02.540 回答
1

我也遇到了同样的问题,但是在添加下面的代码按钮操作正常工作后cell.contentView.userInteractionEnabled = NO;

于 2015-10-30T09:15:49.693 回答
0

如果它使用自动布局,请尝试在 -viewDidAppear 中添加一条日志语句:

NSLog(@"Height of UIView: %f",  self.<name of UIView>.frame.size.height);

如果结果为 0(或不够大),则将 UIView 的高度设置为大于“Discard All”按钮的高度。

于 2013-11-15T13:10:57.083 回答
0

检查父框架内的按钮

于 2015-01-14T22:06:52.600 回答
-1

好的,似乎在 iOS7 中以编程方式创建的按钮不会调用它们的目标。我不知道为什么,但我找到了以下解决方案:

  1. 在InterFace Builder(或nib)中添加一个按钮并自定义并隐藏它。( theButtonInTheNib);

  2. 使其成为 IBOutlet 属性:@property (strong) IBOutlet UIButton *theButtonInTheNib

  3. 建立目标 IBAction 连接:(IBAction)theTargetAction:(id)sender;

诀窍来了。我们将复制/或复制此按钮:

NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:theButtonInTheNib];
UIButton *theCopyButton = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
[theCopyButton setHidden:NO];
[theCopyButton setFrame:CGRectMake(x, y, width, height)];
[theCopyButton addTarget:self action:@selector(theTargetAction:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:theCopyButton];

我再次添加了目标操作,但任何其他操作都可以。

于 2014-04-27T22:59:03.290 回答