【问题标题】:identify touches on subclass of UIViews created programmatically in iOS识别在 iOS 中以编程方式创建的 UIView 子类的触摸
【发布时间】:2013-07-09 17:24:18
【问题描述】:

我正在创建一个带有卡片的应用程序。在我的 mainViewController 中,我有以下代码:

CardView *cardView = [[CardView alloc] initWithFrame:CGRectMake(0, 0, CardWidth, CardHeight)];
                    cardView.card = [player.closedCards cardAtIndex:t];
                    [self.cardContainerView addSubview:cardView];
                    [cardView animateDealingToBottomPlayer:player withIndex:t withDelay:delay];
                    delay += 0.1f;

其中 CardView 是 UIView 的子类。每张卡片都是一个独特的卡片视图,在 CardView.m 中我确实有:

@implementation CardView
{
    UIImageView *_backImageView;
    UIImageView *_frontImageView;
    CGFloat _angle;
}

@synthesize card = _card;

- (id)initWithFrame:(CGRect)frame
{
    if ((self = [super initWithFrame:frame]))
    {
        self.backgroundColor = [UIColor clearColor];
        [self loadBack];
        self.userInteractionEnabled=YES;
    }
    return self;
}

- (void)loadBack
{
    if (_backImageView == nil)
    {
        _backImageView = [[UIImageView alloc] initWithFrame:self.bounds];
        _backImageView.image = [UIImage imageNamed:@"Back"];
        _backImageView.contentMode = UIViewContentModeScaleToFill;
        [self addSubview:_backImageView];
    }
}

以及其他功能的实现。

由于为了赢得空间,将一张牌放在其他牌的顶部(一张牌的一半可见,其余的被下一张牌覆盖,依此类推),我想识别每张牌上的触摸。

如果我将该代码放在 CardView 中:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"Card is touched");
}

它永远不会被调用。如果我将它放在 GameView 控制器中,它会在我将触摸的任何地方被调用,但我不知道如何识别调用了哪个 cardView。能给我一个提示吗?

编辑: 我决定使用手势。因此在我的 mainViewController 中将代码更改为:

for (PlayerPosition p = startingPlayer.position; p < startingPlayer.position + 4; ++p)
{
   CardView *cardView = [[CardView alloc] initWithFrame:CGRectMake(0, 0, CardWidth, CardHeight)];
   cardView.card = [player.closedCards cardAtIndex:t];
   cardView.userInteractionEnabled=YES;
   [self.cardContainerView addSubview:cardView];
   [cardView animateDealingToBottomPlayer:player withIndex:t withDelay:delay];
   delay += 0.1f;
   UITapGestureRecognizer *recognizer=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(cardSelected:)];
   [cardView addGestureRecognizer:recognizer];
}

但这永远不会被调用。

-(void)cardSelected:(UITapGestureRecognizer *)recognizer
{
    NSLog(@"Card Selected with gestures");
}

为什么会这样?

编辑 2:

我也试过添加这个:

self.cardContainerView.userInteractionEnabled=YES; 

或改变这个:

UITapGestureRecognizer *recognizer=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(cardSelected:)];

到这里:

UITapGestureRecognizer *recognizer=[[UITapGestureRecognizer alloc]initWithTarget:self .cardContainerView action:@selector(cardSelected:)];

但它们都不起作用。

【问题讨论】:

  • 你考虑过手势识别器吗?
  • @Wain 老实说,我以前没有使用过它们,也不知道如何实现。你认为这会更容易吗?
  • 这可能不是最好的方法,但您可以获得触摸的 x 和 y,如果您有每张卡片的框架,您可以看到哪一张被触摸了。我会推荐手势识别器。

标签: ios uigesturerecognizer touches


【解决方案1】:

如果您改为向每个卡片视图添加一个轻击手势识别器,您可以获得对您指定的方法的回调,并且手势已连接到视图,因此您可以直接获取对它的引用。


您的CardView(我猜它是UIView 的子类?)有2 个子视图,它们是图像视图:

UIImageView *_backImageView;
UIImageView *_frontImageView;

您可能希望将userInteractionEnabled 设置为其中一个或两个上的YES(取决于卡片应何时可点击以及子视图何时显示和隐藏)。

您还可以充当手势的代表(如果您需要,或者只是暂时调试手势被触发但被其他手势阻止)。

【讨论】:

  • 您将图像视图作为子视图,这些可能会阻止触摸,因为默认情况下它们会禁用 userInteractionEnabled。您应该能够在没有副作用的情况下启用触摸。
  • 您的意思是否与此不同:cardView.userInteractionEnabled=YES; ?上面的代码发生在一个 for 循环中,如果它有什么不同的话。
  • 你猜对了,它是 UIView 的子类。我应该留下其余的 userInteractionEnables 吗?现在代表的代码被注释了。我已经为 UIImageView 添加了 userInteractionEnabled 但又没有。您能否提议对我的代码进行更改,因为我尝试的任何组合似乎都不起作用。
  • 好的,将目标保留为 self,注释(所有)前后图像视图的代码(然后您可以判断它们是否导致问题)。只需接触卡片视图的工作原理,然后逐个添加每个子视图即可找到阻止程序。
  • 不工作了。我会从头再来检查。 target 是 self,为 for 循环中的每个 cardView 启用 userInteraction,并且每个 cardView 都作为子视图添加到 cardContainerView 中(其中无论是否启用 userInteraction 都没有区别 - 这也是 UIView 的子类)。
猜你喜欢
  • 1970-01-01
  • 2018-08-22
  • 1970-01-01
  • 2018-06-04
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多