How to create bubbles and arrows on the iPhone help page about using buttons?

Most apps today have a tutorial that talks about how to use buttons in an app. This man page is usually black with a small alpha value (therefore only semi-translucent) with a bubble box containing text to identify controls and an arrow pointing to the corresponding component.

Here is an example image .. (From MyThings app)

This is a normal page.

enter image description here

And if you swipe your finger from bottom to top, a help view will appear, like ..

enter image description here

Here are my doubts:

  • Which one is best to create images and text in this reference view? Drawing images and texts using Core Graphics or just installing a UIImageView with a png image? Which one is effective?

  • There is no problem when implementing a UIImageView with a ready-made png image. As far as I know, the problem is the image file size and load time. If we look at the drawing method, my thoughts are about the following issues.

  • Drawing a rectangle is so simple. ( See here ). But what about drawing a rectangle with curved corners? Is there any function that handles this case?

  • The arrow then points to the corresponding component. How to find the exact point to be indicated? (before iPhone 4S, no problem, I hope the iPhone 5 has different heights)

  • How to draw these pointers from a specific position in a rectangle?

Any ideas?

Just confused !!

+4
source share
3 answers
  • To draw bubbles and arrows using CG is better, IMHO. It will work even if you completely change the application (if you draw them correctly, pointing, for example, to the center of the button). With images, you will need to have multiple copies for different resolutions and display scales. In addition, you will need to update the arrows if you change anything.

  • I do not see a lack of performance. Both methods draw bubbles very quickly. Also think that you can cache the generated CG images for future use.

  • See these questions to learn how to draw bubbles:

  • It seems logical to use the center of the button for each bubble point. Your drawing methods should know where to point the arrow and the current orientation (if the application rotates). He must consider other bubbles to avoid coincidence. You can divide the space in rows and columns and assign free space for each bubble.

  • For better user convenience, these bubbles should not consume taps. If you press the button when the bubbles are visible, you need to perform the intended action (instead of just hiding the bubbles and requiring a second tap).

+2
source

in your case, I will refer to mutable and reusable images. I also have many overlay screens in my application, and I ended up with 5 6 generic arrow elements, label backgrounds and a rectangular background for uilabel.

I know that drawing a rectangle is easy, but sometimes it can just be overloading.

if you want to change the direction of these arrows, you can apply the layer transform to UIImageview, as shown below:

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

and for the rounded corners of the rectangles, I assume that you can use the user's text fields with a specific background color and set the cornerradius property of their layers.

+2
source

Finally I did it!

From my one-day experience, I learn that there are three ways to deal with this situation.

  • Just create your desired images as png files and just use UIImageView to display. (But remember, you must have the same image with different resolutions, which will increase the size of your application).

  • The second way: show bubbles (or possibly a rectangle) by creating labels, text fields, etc. with arrow. You can simply convert the image to reposition the arrow pointer. (As Ilker Baltachi said in the previous answer).

  • The third way is from Core Graphics. You can draw whatever you want. As far as I know, increasing the size of the application or increasing memory consumption by initializing / allocating / saving labels and text fields, we can try this with Core Graphics.

I have three views where I want to implement this help screen. For all three screens, I can use any of the three methods, because there is not much difference related to performance if we use it for little needed situations. But I tried with the third way, because, I really did not know anything about Core Graphics. So it’s easy to learn.

The problems I encountered :

  • The arrow should point to the center of the button (or possibly to the top of the button). Therefore, finding the exact location is difficult. I used this function on only 3 pages in my application. Each page contains a maximum of 4 icons for description. So I just encoded the values ​​(another good luck, the application does not support landscape mode). But if you want to use this function for so many pages, you have to define some arrays and a method that finds the center of the icons, calculating its center with reference to their origin, height and width, blah, blah ..

  • Another problem is that you have to make sure that the bubbles do not cross anywhere. It also needs a global method that finds a location for each bubble. The size of the bubble depends on the size of the text that will be placed inside it. This is a more complex problem, and in just 3 screens I will not define a global method with hundreds of calculations. So again, I just encoded the starting point, the height and width of each bubble with reference to self.view

  • And last but not least. The Arrow !! The height of the arrow may vary depending on the location of the bubble. The width of the bubble can also vary in height. In addition, you should know the side and points of the bubble from which the arrow goes to the button. If you have already fixed the places of the bubbles in your mind, this is not a problem for you ..: P

Now let's get the coding part,

 - (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); ....... ....... } 

You can call this method from the drawRect: method, like this.

 [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"]; 

And the final image will be like that.

enter image description here

I skipped the triangle shaped arrow because this type of arrow gives a handwriting effect.

Thanks to @djromero and Ilker Baltaci for your valuable answers.

My next perplexity is to draw texts !!!!!: P

+1
source

Source: https://habr.com/ru/post/1435904/


All Articles