【问题标题】:How to create bubbles & arrows in iPhone help page about using buttons?如何在有关使用按钮的 iPhone 帮助页面中创建气泡和箭头?
【发布时间】:2012-09-24 11:58:10
【问题描述】:

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

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

这是正常页面

如果你从下往上滑动,帮助视图会像..

这是我的疑惑:

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

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

  • 画一个矩形就是这么简单。 (Refer here)。但是如何绘制一个带有弯曲角的矩形呢?有没有可以处理这种情况的函数?

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

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

有什么想法吗?

只是一头雾水!!

【问题讨论】:

    标签: iphone helper drawrect


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

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

    • 查看这些问题以了解如何绘制气泡:

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      【讨论】:

        【解决方案3】:

        我终于做到了!!

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

        • 只需将所需的图像创建为 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

        【讨论】:

        • 绘制文本是最简单的。您可以使用 - (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode
        • 非常感谢..我可以使用上述方法绘制文本。如何参考要绘制的字符串找到矩形的大小?有什么建议吗?
        • 我需要找到字符串高度,因为我想在气泡的中心显示字符串。
        • CGSize expectedLabelSize = [yourString sizeWithFont:aFont constrainedToSize:maximumLabelSize alineBreakMode];
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-22
        • 2019-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多