iPhone:如何以编程方式制作小费气球?

时间:2011-05-18 18:57:25

标签: iphone uiview uilabel

请提供代码以编程方式制作小费气球,就像Grindr一样。

我想根据文字和文字自动调整大小。字体大小。 而且,我希望能够改变箭头的位置。 如果它结束了,它应该是一个直角三角形。否则,它应该是一个等边三角形。

tip balloon

3 个答案:

答案 0 :(得分:8)

// AppDelegate.h

@interface AppDelegate : NSObject <UIApplicationDelegate> {

}

@property (nonatomic, retain) UIWindow *window;

@end

// AppDelegate.m

#import "AppDelegate.h"
#import "TipBalloon.h"

@implementation AppDelegate

@synthesize window;

#pragma mark NSObject

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

#pragma mark UIApplicationDelegate

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    // Add the tip balloon.
    TipBalloon *textExample =
    [[TipBalloon alloc] initAtPoint:CGPointMake(6.0f, 30.0f) withText:
     @"Hello world! I like to make things. Yay! They are really cool things!"];
    [window addSubview:textExample];
    [textExample release];

    window.backgroundColor = [UIColor brownColor];
    [window makeKeyAndVisible];
    return YES;
}

@end

// TipBalloon.h

@interface TipBalloon : UIView {

}

@property (nonatomic, copy) NSString *text;

- (id)initAtPoint:(CGPoint)point withText:(NSString *)string;
- (void)drawOutlineInContext:(CGContextRef)context;
- (void)drawTextInContext:(CGContextRef)context;

@end

// TipBallon.m

#import "TipBalloon.h"

// TODO make some of these instance variables to add more customization.
static const CGFloat kArrowOffset = 0.0f;
static const CGFloat kStrokeWidth = 2.0f;
static const CGFloat kArrowSize = 14.0f;
static const CGFloat kFontSize = 12.0f;
static const CGFloat kMaxWidth = 196.0f;
static const CGFloat kMaxHeight = CGFLOAT_MAX;
static const CGFloat kPaddingWidth = 12.0f;
static const CGFloat kPaddingHeight = 10.0f;

@implementation TipBalloon

@synthesize text;

#pragma mark NSObject

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

#pragma mark UIView

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    [self drawOutlineInContext:contextRef];
    [self drawTextInContext:contextRef];
}

#pragma mark TipBalloon

- (id)initAtPoint:(CGPoint)point withText:(NSString *)string {
    CGSize size = [string sizeWithFont:[UIFont systemFontOfSize:kFontSize]
                     constrainedToSize:CGSizeMake(kMaxWidth, kMaxHeight)
                         lineBreakMode:UILineBreakModeWordWrap];
    CGRect rect = CGRectMake(point.x, point.y, size.width+kPaddingWidth*2.0f,
                             size.height+kPaddingHeight*2.0f+kArrowSize);
    if ((self = [super initWithFrame:rect])) {
        self.text = string;
        UIColor *clearColor = [[UIColor alloc] initWithWhite:0.0f alpha:0.0f];
        self.backgroundColor = clearColor;
        [clearColor release];
    }
    return self;
}

- (void)drawOutlineInContext:(CGContextRef)context {
    CGRect rect = self.bounds;
    rect.origin.x += (kStrokeWidth/2.0f);
    rect.origin.y += kStrokeWidth + kArrowSize;
    rect.size.width -= kStrokeWidth;
    rect.size.height -= kStrokeWidth*1.5f + kArrowSize;

    CGFloat radius = 11.0f;
    CGFloat x_left = rect.origin.x;
    CGFloat x_right = x_left + rect.size.width;
    CGFloat y_top = rect.origin.y;
    CGFloat y_bottom = y_top + rect.size.height;

    CGContextBeginPath(context);
    CGContextSetLineWidth(context, kStrokeWidth);
    CGContextSetRGBStrokeColor(context, 0.0f/255.0f, 255.0f/255.0f, 0.0f/255.0f, 1.0f); // green
    CGContextSetGrayFillColor(context, 1.0f, 1.0f); // white background
    CGContextMoveToPoint(context, x_left+radius, y_top);
    CGContextAddLineToPoint(context, x_left+radius+kArrowOffset, y_top);

    // Draw triangle.
//    CGContextAddLineToPoint(context, x_left+radius+kArrowOffset+kArrowSize/2.0f, y_top-kArrowSize);
    CGContextAddLineToPoint(context, x_left+radius+kArrowOffset, y_top-kArrowSize);
    CGContextAddLineToPoint(context, x_left+radius+kArrowOffset+kArrowSize, y_top);

    static const CGFloat F_PI = (CGFloat)M_PI;
    CGContextAddArc(context, x_right-radius, y_top+radius, radius, 3.0f*F_PI/2.0f, 0.0f, 0);
    CGContextAddArc(context, x_right-radius, y_bottom-radius, radius, 0.0f, F_PI/2.0f, 0);
    CGContextAddArc(context, x_left+radius, y_bottom-radius, radius, F_PI/2.0f, F_PI, 0);
    CGContextAddArc(context, x_left+radius, y_top+radius, radius, F_PI, 3.0f*F_PI/2.0f, 0);
    CGContextClosePath(context);
    CGContextDrawPath(context, kCGPathFillStroke);
}

- (void)drawTextInContext:(CGContextRef)context {
    CGRect rect = self.bounds;
    rect.origin.x += kPaddingWidth;
    rect.origin.y += kPaddingHeight + kArrowSize;
    rect.size.width -= kPaddingWidth*2.0f;
    rect.size.height -= kPaddingHeight*2.0f;

    CGContextSetGrayFillColor(context, 0.0f, 1.0f); // black text
    [text drawInRect:rect withFont:[UIFont systemFontOfSize:kFontSize]
       lineBreakMode:UILineBreakModeWordWrap];
}

@end

答案 1 :(得分:2)

我不会添加另一个视图只是为了将三角形放在上面,您是否考虑使用UIBezierPath绘制圆角边框和三角形?这将为您的绘图提供更大的灵活性,您可以将所有内容保存在一个视图中。

答案 2 :(得分:0)

您可以在主视图中使用UIView,并在需要时调用它。但是,您必须使UIView透明,并且可能需要使用图像作为气球的主要部分。在这种情况下,您只需使用UILabel来设置所需的消息。