UIButton 在 iOS 7 中无法正常工作

Posted

技术标签:

【中文标题】UIButton 在 iOS 7 中无法正常工作【英文标题】:UIButton not working correctly in iOS 7 【发布时间】:2013-09-30 14:14:57 【问题描述】:

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

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

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

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

有人有什么想法吗?

谢谢!

【问题讨论】:

【参考方案1】:

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

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

我解决了这个问题,将视图的框架放置在正确的位置,使其覆盖按钮。

如果我能找到与此相关的任何文档,我会在这里发布。

谢谢!

【讨论】:

请详细说明你的答案。我也面临同样的问题。 我发现问题是我将每个 UIView 的背景颜色设置为不同且明显可见的颜色。基本上,UIViewController 中嵌入了另一个 UIViewController。此嵌入式视图控制器的框架已设置为使按钮不在框架内。这就是为什么它不起作用。我增加了框架的大小,以便带有按钮的 UIView 位于该框架内。如果您愿意,可以将您的代码/xib 发送给我,如果不清楚,我可以看看。 我通过设置 userInteractionEnabled = NO of cell.contentView 解决了我的问题。 :) 感谢您的回复 :) 编码愉快 啊,是的,这是一个很好的解决方案。除了在我的情况下,损坏的按钮不是 tableView 单元格,因此它没有 contentView 属性。祝你编码愉快:D 当我从我的 iOS7 特定代码中删除 [tableHeaderView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; 时,我的 UIButton 又开始工作了。否则 tableHeaderView 没有正确的框架可以使用。【参考方案2】:

我刚遇到这个问题。根据 @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];

【讨论】:

谢谢分享。这是一个很好的解决方法。非常令人印象深刻! 很好的解决方案。这个答案也帮助了我:***.com/a/5433189/2385538【参考方案3】:

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

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

默认情况下,hittest 函数会跳过检查超出边界的视图。

最热门的例子:https://***.com/questions/17246488/best-way-to-perform-the-hit-test-objective-c。

【讨论】:

【参考方案4】:

不确定这是否相同,但可能相关:

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

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

【讨论】:

谢谢,这也是有效的。但是在这种情况下没有 UIGestureRecognizers。【参考方案5】:

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

【讨论】:

我必须将其设置为 NO。【参考方案6】:

我遇到了同样的问题 - 按钮在 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]];

【讨论】:

【参考方案7】:

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

【讨论】:

【参考方案8】:

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

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

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

【讨论】:

【参考方案9】:

检查父框架内的按钮

【讨论】:

【参考方案10】:

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

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

    将其设为 IBOutlet 属性:@property (strong) IBOutlet UIButton *theButtonInTheNib

    建立目标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];

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

【讨论】:

如果以编程方式创建按钮,肯定会调用它们的目标。 只是不需要做存档探戈来激活按钮。

以上是关于UIButton 在 iOS 7 中无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

UIButton 圆角半径在 CustomClass 中无法正常工作

NSUserDefaults 在 iOS 7 中无法正常工作

iOS:自定义按钮(UIButton 的子类) - 无法更改边框属性

向左滑动删除单元格在 ios 8 中无法正常工作,但在 ios 7 中有效

UIButton.addTarget 无法正常工作。似乎是一个时间问题?

UITableView 自定义单元格中的 UIButton 触摸无法正常工作