4

今天的大多数应用程序都提供教程,教用户如何使用应用程序中的按钮。这个帮助页面通常是黑色的,带有一点 alpha 值(所以只有背景是半可见的),带有一个气泡框,其中包含定义控件的文本和指向相应组件的箭头。

这是示例图像..(来自应用程序MyThings

这是正常页面

在此处输入图像描述

如果您从下到上滑动,帮助视图将显示为..

在此处输入图像描述

这是我的疑问:

  • 哪一个最适合在此帮助视图中创建图像和文本?使用 Core Graphics 或简单地将 UIImageView 与 png 图像一起绘制图像和文本?哪一个是高效的?

  • 用现成的 png 图片实现 UIImageView 是没有问题的。据我所知,这里的问题是图像文件大小和加载时间。如果我们考虑绘图方法,我的脑海中关于以下问题的事情。

  • 画一个长方形就是这么简单。(参考这里)。但是如何绘制一个带有弯曲角的矩形呢?是否有任何功能可以处理这种情况?

  • 然后是指向相应组件的箭头。我们如何找到应该指向的确切点?(直到 iPhone 4S,我希望没有问题,iPhone 5 有不同的高度)

  • 如何从矩形中的特定位置绘制这个指针?

有任何想法吗?

只是糊涂!!

4

3 回答 3

2

在你的情况下,我会参考可调整大小和可重复使用的图像。我的应用程序中也有许多覆盖屏幕,我最终为 uilabel 生成了 5 6 个通用项目箭头、标签背景和矩形背景图像。

我知道绘制矩形很容易,但有时可能只是超载。

如果要更改这些箭头的方向,可以将图层转换应用于 UIImageview,如下所示

        arrowIamgeView.transform = CGAffineTransformMakeRotation(-M_PI / 20);

对于矩形的圆角,我假设您可以使用具有特定背景颜色的文本字段并设置其图层的cornerradius 属性。

于 2012-09-24T13:09:30.480 回答
2
  • 恕我直言,用 CG 绘制气泡和箭头更好。即使您完全更改应用程序(例如,如果您正确地将它们绘制为指向按钮的中心),它也会起作用。对于图像,您需要为不同的显示分辨率和比例准备多个副本。此外,如果您更改任何内容,则需要更新箭头。

  • 我没有看到任何性能缺陷。这两种方法都会非常快速地绘制气泡。另外,认为您可以缓存 CG 生成的图像以供将来使用。

  • 请参阅这些问题以了解如何绘制气泡:

  • 使用每个气泡指向的按钮中心似乎是合乎逻辑的。您的绘图方法需要知道箭头指向的位置和当前方向(如果应用程序旋转)。应考虑其他气泡,避免重叠。您可以将空间划分为行和列,并为每个气泡分配可用空间。

  • 为了更好的用户体验,这些气泡不应该消耗水龙头。如果在气泡可见时点击按钮,则应执行预期的操作(而不是仅仅隐藏气泡并需要第二次点击)。

于 2012-09-24T13:22:25.670 回答
1

最后我做到了!!

根据我一天的经验,我知道有三种方法可以处理这种情况。

  • 只需将所需的图像创建为 png 文件,然后使用 UIImageView 来显示。(但请记住,您应该拥有具有不同分辨率的相同图像。这会增加您的应用程序大小)。

  • 第二种方法是,通过创建标签、文本字段等来显示气泡(或者可能是一个矩形)。带有箭头图像。您可以简单地变换图像以更改箭头的指向位置。(正如 Ilker Baltaci 在之前的回答中所说)。

  • 第三种方式是通过 Core Graphics。你可以在这里画任何你想要的东西。据我所知,通过初始化/分配/保留标签和文本字段来增加应用程序的大小或增加内存消耗,我们可以通过 Core Graphics 进行尝试。

我想在三个视图中实现此帮助屏幕工具。对于三个屏幕,我可以使用三种方法中的任何一种,因为如果我们将它用于很少需要的情况,则与性能没有太大区别。但是我尝试了第三种方式,因为我真的对Core Graphics一无所知。所以只是为了学习。。

我面临的问题

  • 箭头应该指向按钮的中心(或者可能是按钮的顶部)。所以找到这个确切的位置很复杂。我只在我的应用程序的 3 个页面中使用了此功能。每页最多包含 4 个图标来描述。所以我只是硬编码了这些值(我的另一个幸运是,该应用程序不支持横向模式)。但是,如果你想在这么多页面上使用这个特性,你应该定义一些数组和一个方法,通过参考它们的原点、高度和宽度、等等来计算图标的中心来找到图标的中心。

  • 另一个问题是,您应该确保气泡不会在任何地方重叠。在这里,我们还需要一个全局方法来找到每个气泡的位置。气泡的大小取决于要放置在其中的文本大小。这是一个更复杂的问题,对于仅 3 个屏幕,我不会定义一个包含数百次计算的全局方法。所以我再次参考self.view对每个气泡的原点、高度和宽度进行了硬编码

  • 最后但并非最不重要的......箭头!箭头的高度可能随气泡的位置而变化。气泡的宽度也可能随高度而变化。此外,您应该知道箭头指向按钮的气泡的边和点。如果您已经在脑海中修复了气泡的位置,那么这些对您来说根本不是问题..:P

现在让我们来编码部分,

- (void) createRect:(CGRect)rect xPoint:(float)x yPoint:(float)y ofHeight:(float)height ofWidth:(float)width toPointX:(float)toX toPointY:(float)toY withString:(NSString *)helpString inDirection:(NSString *)direction
{
    float distance = 5.0;
    float widthOfLine = 5.0;
    float arrowLength = 15.0;

    //Get current context

    CGContextRef context = UIGraphicsGetCurrentContext();

    //Set width of border & colors of bubble

    CGContextSetLineWidth(context, widthOfLine);
    CGContextSetStrokeColorWithColor(context, [[UIColor darkGrayColor] CGColor]);
    CGContextSetFillColorWithColor(context, [[UIColor colorWithRed:0 green:0 blue:0 alpha:0.9] CGColor]);

    CGContextBeginPath(context);
    CGContextMoveToPoint(context, x, y);

    CGContextAddLineToPoint(context, x+width, y);
    CGContextAddQuadCurveToPoint(context, x+width, y, x+width+distance, y+distance);

    CGContextAddLineToPoint(context, x+width+distance, y+distance+height);
    CGContextAddQuadCurveToPoint(context, x+width+distance, y+distance+height, x+width, y+distance+height+distance);

    CGContextAddLineToPoint(context, x, y+distance+height+distance);    
    CGContextAddQuadCurveToPoint(context, x, y+distance+height+distance, x-distance, y+distance+height);

    CGContextAddLineToPoint(context, x-distance, y+distance);
    CGContextAddQuadCurveToPoint(context, x-distance, y+distance, x, y);

    CGContextDrawPath(context, kCGPathFillStroke);

    //Draw curvely arrow from bubble to button (but without arrow mark)

    CGContextBeginPath(context);
    CGContextSetLineWidth(context, 5.0);
    CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);

    CGPoint startPoint = CGPointMake(x+(width/2.0), y+distance+distance+height);

    CGPoint endPoint = CGPointMake(toX, toY);

    CGContextMoveToPoint(context, startPoint.x, startPoint.y+5.0);

    if ([direction isEqualToString:@"left"])
    {
        CGContextAddCurveToPoint(context, startPoint.x, startPoint.y+5.0, endPoint.x, endPoint.y, toX-10, toY);
    }

    else
    {
        CGContextAddCurveToPoint(context, startPoint.x, startPoint.y+5.0, endPoint.x, endPoint.y, toX+10, toY);
    }

    CGContextStrokePath(context);

    //Draw the arrow mark

    CGContextBeginPath(context);
    CGContextSetLineWidth(context, 5.0);
    CGContextSetStrokeColorWithColor(context, [[UIColor whiteColor] CGColor]);

    if ([direction isEqualToString:@"left"])
    {
        CGContextMoveToPoint(context, toX-10.0, toY-arrowLength);

        CGContextAddLineToPoint(context, toX-10.0, toY);
        CGContextAddLineToPoint(context, toX-10.0+arrowLength, toY);
    }

    else
    {
        CGContextMoveToPoint(context, toX+10.0, toY-arrowLength);

        CGContextAddLineToPoint(context, toX+10.0, toY);
        CGContextAddLineToPoint(context, toX+10.0-arrowLength, toY);
    }

    CGContextStrokePath(context);

    .......
    .......
}

您可以从这样的方法中调用此方法drawRect:..

[self createRect:rect xPoint:30.0 yPoint:250.0 ofHeight:100.0 ofWidth:100.0 toPointX:48.0 toPointY:430.0 withString:@"xxxxxxx" inDirection:@"left"];

[self createRect:rect xPoint:160.0 yPoint:100.0 ofHeight:100.0 ofWidth:100.0 toPointX:260.0 toPointY:420.0 withString:@"yyyyyyy" inDirection:@"right"];

最终的图像将是这样的..

在此处输入图像描述

我跳过了三角形箭头,因为这种箭头类型会产生手写效果。

感谢 @djromero 和 Ilker Baltaci 提供的宝贵答案。

我的下一个困惑是关于绘图文本!!!!!!:P

于 2012-09-25T13:19:50.547 回答