3

我正在使用适用于 iOS 的 Mixare AR SDK,我需要解决一些发生的错误,其中之一是在点击 POI 的视图时显示 POI 的信息。

序幕:

Mixare 在 MarkerView 视图中放置了一个覆盖 UIView,MarkerView 视图在屏幕上移动以定位 POI,每个视图都有两个子视图,一个 UIImageView 和一个 UILabel。

问题:

现在,例如,屏幕中有 3 个可见 POI,因此有 3 个 MarkerView 作为覆盖子视图。如果您触摸覆盖中的任何位置,则会显示与可见的随机 POI 关联的信息视图。

期望:

我希望仅当用户点击 MarkerView 时才显示相关的 POI 信息

开始干活。我看到 MarkerView 继承自 UIView 并实现了 hitTest:withEvent

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    viewTouched = (MarkerView*)[super hitTest:point withEvent:event];
    return self;

}

我已经放置了一个断点,并且每个可见的 MarkerView 都会调用一次 hitTest,但loadedView 总是为空,所以我无法使用它,所以我尝试检查命中点是否在实现 pointInside:withEvent 的 MarkerView 框架内:通过这种方式

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    NSLog(@"ClassName: %@", [[self class] description]);
    NSLog(@"Point Inside: %f, %f", point.x, point.y);
    NSLog(@"Frame x: %f y: %f widht:%f height:%f", self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);

    if (CGRectContainsPoint(self.frame, point))
        return YES;
    else
        return NO;


    return YES;
}

但是这个函数总是返回 NO,即使我触摸了 MarkerView。当我检查日志时,我看到 X 和 Y 点值有时具有负值,并且视图的宽度和高度非常小,0.00022 或类似值,而不是我在初始化时设置 MarkerView 框架的 100 x 150。

这是我的日志的摘录,您可以在其中看到类名、点和 MarkerView 帧值。

ClassName: MarkerView
2011-12-29 13:20:32.679 paisromanico[2996:707] Point Inside: 105.224899, 49.049023
2011-12-29 13:20:32.683 paisromanico[2996:707] Frame x: 187.568573 y: 245.735138 widht:0.021862 height:0.016427

我对这个问题非常迷茫,所以欢迎任何帮助。提前感谢您提供的任何帮助,我很抱歉这块砖:(

编辑:

最后我发现问题不在于 hitTest:withEvent: 或 pointInside:withEvent,问题在于 CGTransform 应用于 MarkerView 以基于距离和旋转视图进行缩放,如果我评论与此相关的任何代码, Mixare AR SDK 工作正常,我的意思是,如果您触摸标记,信息视图会正确显示,如果触摸屏幕中的任何其他位置,则不会执行任何操作。

所以,到目前为止,我还没有解决这个问题,但我应用了一个补丁来删除 AugmentedViewController.m 类中的 CGTransform 相关代码 - (void)updateLocations:(NSTimer *)timer 函数

- (void)updateLocations:(NSTimer *)timer {
    //update locations!

    if (!ar_coordinateViews || ar_coordinateViews.count == 0) {
        return;
    }

    int index = 0;
    NSMutableArray * radarPointValues= [[NSMutableArray alloc]initWithCapacity:[ar_coordinates count]];

    for (PoiItem *item in ar_coordinates) {

        MarkerView *viewToDraw = [ar_coordinateViews objectAtIndex:index];
        viewToDraw.tag = index;

        if ([self viewportContainsCoordinate:item]) {

            CGPoint loc = [self pointInView:ar_overlayView forCoordinate:item];
            CGFloat scaleFactor = 1.5;

            if (self.scaleViewsBasedOnDistance) {
                scaleFactor = 1.0 - self.minimumScaleFactor * (item.radialDistance / self.maximumScaleDistance);
            }

            float width = viewToDraw.bounds.size.width ;//* scaleFactor;
            float height = viewToDraw.bounds.size.height; // * scaleFactor;

            viewToDraw.frame = CGRectMake(loc.x - width / 2.0, loc.y-height / 2.0, width, height);

            /*
            CATransform3D transform = CATransform3DIdentity;

            //set the scale if it needs it.
            if (self.scaleViewsBasedOnDistance) {
                //scale the perspective transform if we have one.
                transform = CATransform3DScale(transform, scaleFactor, scaleFactor, scaleFactor);
            }

            if (self.rotateViewsBasedOnPerspective) {
                transform.m34 = 1.0 / 300.0;

                double itemAzimuth = item.azimuth;
                double centerAzimuth = self.centerCoordinate.azimuth;
                if (itemAzimuth - centerAzimuth > M_PI) centerAzimuth += 2*M_PI;
                if (itemAzimuth - centerAzimuth < -M_PI) itemAzimuth += 2*M_PI;

                double angleDifference = itemAzimuth - centerAzimuth;
                transform = CATransform3DRotate(transform, self.maximumRotationAngle * angleDifference / (VIEWPORT_HEIGHT_RADIANS / 2.0) , 0, 1, 0);
            }            

            viewToDraw.layer.transform = transform;

             */
            //if we don't have a superview, set it up.
            if (!(viewToDraw.superview)) {
                [ar_overlayView addSubview:viewToDraw];
                [ar_overlayView sendSubviewToBack:viewToDraw];
            }
        } else {
            [viewToDraw removeFromSuperview];
            viewToDraw.transform = CGAffineTransformIdentity;
        }
        [radarPointValues addObject:item];
        index++;
    }
    float radius = [[[NSUserDefaults standardUserDefaults] objectForKey:@"radius"] floatValue];
    if(radius <= 0 || radius > 100){
        radius = 5.0;
    }

    radarView.pois = radarPointValues;
    radarView.radius = radius;
    [radarView setNeedsDisplay];
    [radarPointValues release];
}

任何 CoreGraphics 或 UI 专家都可以就这个问题给我们他的观点吗?

4

1 回答 1

1

您应该尝试按附件进行命中测试:

if ([self pointInside:point withEvent:event]) {
    // do something 
}

我建议您在superview上添加命中测试,并在markerViews的父级的命中测试中执行以下操作

if ([markerView pointInside:point withEvent:event]) {
    // extract the tag and show the relevant info
}

希望这可以帮助

于 2011-12-30T12:49:07.210 回答