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 中有效