【发布时间】:2015-08-07 15:21:50
【问题描述】:
我正在以编程方式使用自动布局。我有一个简单的UIViewController 和一些控件,包括并排排列的两个UIButtons。我经常将相关控件分组到 UIView 中,作为容器,使 groups-of-controls 的排列更易于管理。您将在下面看到 _iapButtonsView,它包含两个按钮和一些垫片。
我的问题。在以下示例中,我被我认为是对约束的有效更改所吸引,这实际上导致UIButtons 没有接收触摸事件。
代码提取 - 按钮确实接收触摸事件的约束:
- (void)viewDidLoad
{
[super viewDidLoad];
...
_buyButton = [ViewCreationHelper createRoundedBorderButtonBold];
[_buyButton addTarget:self action:@selector(buyTap:) forControlEvents:UIControlEventTouchUpInside];
_restoreButton = [ViewCreationHelper createRoundedBorderButton];
[_restoreButton addTarget:self action:@selector(restorePurchaseTap:) forControlEvents:UIControlEventTouchUpInside];
_iapButtonsView = [UIView new];
_iapButtonsView.translatesAutoresizingMaskIntoConstraints = NO;
[contentView addSubview:_iapButtonsView];
...
[_iapButtonsView addSubview:_buyButton];
[_iapButtonsView addSubview:_restoreButton];
// Constraints
NSDictionary* views = NSDictionaryOfVariableBindings(scrollView, contentView, iapDesciption, _iapButtonsView, _buyButton, _restoreButton, spacer1, spacer2, spacer3);
...
constraints = [NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-25-[iapDesciption]-40-[_iapButtonsView]|"
options:0
metrics:nil
views:views];
[contentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[_iapButtonsView]-20-|" options:0 metrics:nil views:views];
[contentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[spacer1][_buyButton(==120.0)][spacer2(==spacer1)][_restoreButton(==_buyButton)][spacer3(==spacer1)]|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:views];
[_iapButtonsView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_buyButton(==80.0)]|" options:0 metrics:nil views:views];
[_iapButtonsView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_restoreButton(==80.0)]|" options:0 metrics:nil views:views];
[_iapButtonsView addConstraints:constraints];
...
}
有问题的约束是_iapButtonsView 的垂直约束。在开发过程中(这是一个应用内购买屏幕)我在底部有一些 debug 控件,这就是为什么我将尾随 | 连接到超级视图的底部边缘,如下所示:
constraintsWithVisualFormat:@"V:|-25-[iapDesciption]-40-[_iapButtonsView][someSpacer][someControls]|"
当我取出那些 debug 控件时,我将这些约束更改为:
constraintsWithVisualFormat:@"V:|-25-[iapDesciption]-40-[_iapButtonsView]"
认为这更正确:它们是从顶部锚定的,只有 _iapButtonsView 从它的子视图(主要是两个按钮)获取它的大小,所以我不应该连接到底部边缘的superview...
进行该更改后,按钮不再接收触摸事件。为了进行实验,我尝试显式设置_iapButtonsView 的垂直大小,但仍然没有连接到超级视图的底部边缘,例如
constraintsWithVisualFormat:@"V:|-25-[iapDesciption]-40-[_iapButtonsView(==80.0)]"
有了这些限制,按钮仍然不会接收到触摸事件。
我不明白什么?
(编辑:根据 daddy warbucks 的建议,我删除了上面代码中重复的 [contentView addSubview:_iapButtonsView];)
【问题讨论】:
-
我经常遇到意外地将视图的宽度或高度更改为 0 的约束。你能设置
_iapButtonsView.clipsToBounds = YES看看这是否揭示了问题吗?如果是这样,您的按钮应该会消失。 -
感谢您的建议。我会试一试,虽然我已经尝试给 _iapButtonsView 一个背景颜色......它显示为预期的大小。
-
这也说明了 iabButtonsView 的问题。也许是按钮本身在改变大小。
-
@DanLoughney - 我试过
_iapButtonsView.clipsToBounds = YES,但没有发现问题。与其他实验一起,我认为_iapButtonsView的大小是正确的...只是不确定为什么限制会导致没有触摸事件通过...谢谢。
标签: ios objective-c cocoa-touch autolayout