2011-05-18 66 views
1

請提供代碼來編程提示氣球,就像Grindr一樣。iPhone:如何編程提示氣球?

我想根據文字& font-size自動調整大小。 而且,我希望能夠改變箭頭的位置。 如果它結束了,它應該是一個直角三角形。否則,它應該是一個等邊三角形。

tip balloon

+0

你的問題專門問如何使氣球編程,但如果你創建了一個PNG文件,加載它變成'UIImage'併發送你會在做左/頂帽的寬度,從字面上15分鐘。你沒有得到氣球提示的動態定位,但如果你不真的需要它,這樣做懶惰的方式可能是一個更好的方法。 – kubi 2011-05-18 20:09:38

回答

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 
0

您可以在主視圖中使用UIView並調用它,當你需要它。然而,你必須使UIView透明,可能需要使用圖像作爲氣球的主要部分。在這種情況下,您可以使用UILabel來設置所需的消息。

2

我不會添加另一個視圖只是將三角形放在它上面,你有沒有考慮用UIBezierPath繪製圓角邊框和三角形?這將爲您提供更多的繪圖靈活性,並且您可以將所有內容保存在一個視圖中。

+0

嗯...我聽說過'UIBezierPath',但不知道如何使用它。你知道任何好的例子嗎?我剛剛結束了使用石英繪製圓角和箭頭的提示氣球。 – ma11hew28 2011-05-19 00:13:09

+0

我不記得我在哪裏學到了什麼,但基本上就像是一個CGPath,但要繪製它,您需要在路徑上而不是在上下文中設置屬性。這個鏈接:http://nachbaur.com/blog/core-animation-part-4看起來是一個很好的例子,但請記住,你不一定需要一個CAShapeLayer來繪製一個UIBezierPath。 – elibud 2011-05-19 13:45:33

+0

很酷。我加了我的解決方案。 http://stackoverflow.com/questions/6049682/iphone-how-to-make-a-tip-balloon-programmatically/6052438#6052438 – ma11hew28 2011-05-26 13:18:09