【问题标题】:need UIButton inside custom UIView respond to touches需要自定义 UIView 中的 UIButton 响应触摸
【发布时间】:2012-05-15 17:41:42
【问题描述】:

我有一个带有一些按钮作为子视图的自定义 UIView。我正在使用 touchesBegan/Moved/Ended 来用用户的手指旋转视图。问题是,当我尝试从按钮拖动/旋转视图时,不会调用 touches 方法。我需要按钮来响应UIControlEventTouchUpInside 事件,但如果它与视图一起拖动,则使我的视图旋转。我查看了this 问题和this 问题,但都无法找到适合我的解决方案。

这是我的自定义视图代码:

- (id)initWithFrame:(CGRect)frame andRadius:(float)Radius andViews:

(NSMutableArray *)AllViews
{
    self = [super initWithFrame:frame];
    if (self) {
        radius = Radius;
        allViews = AllViews;

        for(int i = 0; i < [allViews count]; i++){
            //the "currentView" is a UIButton
            UIView *currentView = (UIView *)[allViews objectAtIndex:i];
            [currentView setFrame:CGRectMake(frame.size.width / 2 - 25 + radius * cos((2 * M_PI / [allViews count]) * i), frame.size.height / 2 - 25 + radius * sin((2 * M_PI / [allViews count]) * i), 50, 50)];
            [self addSubview:currentView];

        }
        [self setBackgroundColor:[UIColor redColor]];
        [self setAlpha:.5];

    }
    return self;
}

//- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
//{
//    for (UIView * view in [self subviews]) {
//        if ([view pointInside:[self convertPoint:point toView:view] withEvent:event]) {
//            return YES;
//        }
//    }
//    return NO;
//}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];

    x = point.x;
    y = point.y;

    NSLog(@"touchesBegan");
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];

    float X = point.x;
    float Y = point.y;

    float a = sqrt(X * X + Y * Y);
    float b = sqrt(x * x + y * y);
    float c = sqrt((x - X) * (x - X) + (y - Y) * (y - Y));

    float alpha = acos((a * a + b * b - (c * c)) / (2 * a * b));
    if(alpha == NAN)
        alpha = 0;

    alpha = -alpha;


    [UIView beginAnimations:@"rotate" context:nil];
    [UIView setAnimationDuration:0];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    self.transform = CGAffineTransformRotate(self.transform, alpha);
    [UIView commitAnimations];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];

    float X = point.x;
    float Y = point.y;

    float a = sqrt(X * X + Y * Y);
    float b = sqrt(x * x + y * y);
    float c = sqrt((x - X) * (x - X) + (y - Y) * (y - Y));

    float alpha = acos((a * a + b * b - (c * c)) / (2 * a * b));

    alpha = -alpha;


    [UIView beginAnimations:@"rotate" context:nil];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    self.transform = CGAffineTransformRotate(self.transform, alpha);
    [UIView commitAnimations];
    NSLog(@"touchesEnded");
}

- (void)dealloc
{
    [allViews release];
    [super dealloc];
}

有什么建议吗?

【问题讨论】:

    标签: iphone uiview touchesbegan touchesmoved


    【解决方案1】:

    也许不是您要找的答案,但是:

    我不确定您为什么希望“手指按下按钮,然后将手指拖出按钮”活动作为拖动/旋转动作被按钮后面的视图拾取。就我而言,如果您将手指放在按钮内,则您正在与按钮交互,而不是与后面的视图交互;如果你在触摸屏幕的同时将手指从按钮上移开,你这样做是为了中止按钮按下(即你已经“武装”它但没有“触发”它),而不是与后面的视图交互。

    所以我的意思是:你为什么要这样做?也许您需要重新考虑您的 UI 设计。

    如果您绝对想这样做,您可能想考虑使用UIGestureRecognizers 而不是touchesBegan 等 - 使用它们时可以更轻松地设置更复杂的场景。但手势识别器并非在所有版本的 iOS 上都可用。

    或者,实现一些看起来像按钮或任何你想要的东西,并使用 touchesBegan 等处理它的触摸(以及视图拖动等) - 即不要使用实际的按钮。

    【讨论】:

      【解决方案2】:

      万一有人遇到类似问题,我会发布我使用的解决方案。我覆盖了另一个用作按钮的UIView 类。在每个touchedBegan/Moved/Ended 中,我实现了按钮单击所需的代码,然后将命令链向上传递到下一个自定义UIView,如下所示:

      - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
      {
          [self.nextResponder touchesBegan:touches withEvent:event];
      }
      
      - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
      {
          [self.nextResponder touchesMoved:touches withEvent:event];
      }
      
      - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
      {
          UITouch *touch = [touches anyObject];
          CGPoint point = [touch locationInView:self];
      
          if (point.x < self.frame.size.width && point.y < self.frame.size.height) {
              NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:[NSString stringWithFormat:@"%d", self.tag], @"tag", nil];
              [[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeFilter" object:self userInfo:userInfo];
          }
      
      
          [self.nextResponder touchesEnded:touches withEvent:event];
      }
      

      请注意,我使用 NSNotifications 将操作发送到包含被覆盖视图的 ViewController。

      【讨论】:

        猜你喜欢
        • 2019-03-30
        • 2018-09-15
        • 2016-05-08
        • 2012-11-12
        • 2016-12-14
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多