我有以下设置。
+- XXXCustomControl : UIControl -------+
| A |
| +- ContentView -------------------+|
| | ||
| | B ||
| | ||
| +---------------------------------+|
+--------------------------------------+
XXXCustomControl是UIControl的子类。它包含一个名为contentView的UIView类型的子视图,其大小小于Control的区域。 该视图具有.userInteractionEnabled = YES;
我需要将该属性设置为YES,因为水平滚动视图会偶尔放入其中,并且它们需要可滚动。如果超级视图(在我们的案例中,内容视图不允许用户交互,则会继承子视图。) 但同时这个XXXCustomControl在其内容视图中不包含滚动视图时不仅需要在区域A中而且在区域B中都可以进行tappable。
所以我在这里有“利益冲突”,因为我要么
1)将内容视图设置为userInteractionEnabled = NO,然后我可以在A和B的内容视图区域中点击空控件,但是我将放在那里的滚动视图将无法滚动..
2)将内容视图设置为userInteractionEnabled = YES但是,如果Control为空,我只能点击区域A来触发触摸事件。
我提出的一个想法是我默认将属性设置为NO,当我填充contentView时,我将其设置为yes。当我清除contentView时,我将属性设置为no。 基本上我希望它一直设置为yes,当它为空时,强制contentView将touchUpInside事件传递给它的superview。
这可能吗?
答案 0 :(得分:15)
您可以尝试在内部视图中覆盖pointInside:withEvent:
方法。当您想要将触摸转发到超级视图时,这将允许您返回NO:
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
if( /* You have content, and you want to receive touches */){
return YES;
}else{
return NO;
}
}
答案 1 :(得分:4)
您可以子类化子视图,并实现
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if (!touchedContent) {
[[self nextResponder] touchesBegan:touches withEvent:event];
} else {
[super touchesBegan:touches withEvent:event];
}
}
答案 2 :(得分:1)
您可以使用另一个UIView来“隐藏”子视图。
*详情:这个UIView是子视图的兄弟姐妹。它具有与子视图相同的大小和位置,背景颜色为浅色。
*解释:新的UIView将触摸,并自动将其传递给superview。
这种方式不需要子类化您的子视图 - 这是一个故事板解决方案。
请尝试这个。玩得开心!
答案 3 :(得分:0)
在超级视图中使用此功能,而不更改子视图代码(因为子视图可能是从其他框架或窗格引入的):
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *view = [super hitTest:point withEvent:event];
if ([view isDescendantOfView:self])
{
NSLog(@"touched inside");
}
return view;
}
答案 4 :(得分:0)
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
if <#condition#> { return true }
else { return false }
}
答案 5 :(得分:0)
如果要从Superview(在您的情况下为XXXCustomControl)而不是内部视图(在您的情况下为ContentView)处理事件,则可以在Superview中编写以下快速代码:
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let view = super.hitTest(point, with: event) else { return nil }
if view.isDescendant(of: self) {
// your custom logic
}
return view
}