2010年12月6日月曜日

iPhoneアプリ開発-邪魔にならないメッセージウィンドウ

loadingのぐるぐるイメージを標準で表示できることを最近知って衝撃を受けているaqubiです。こんばんは。

YES/NOダイアログを表示するほどでもないけど、メッセージを通知したい...ということで、
下や上から、にょきにょきっ と表示されるUIViewを作成してみました。



下の方にある [network not connection]って表示されている所です。
下からにょきにょきっと出てきて、数秒後にするするっと下に下がって消えていきます。

イメージのように角丸にしたくて検索していたのですが、よく引っかかる

view.layer.cornerRadius = 5;

という方法が最新のSDKではできないんですかねぇ?
結局ごりごり書いてます。

UIViewのアニメーションは beginAnimations, commitAnimations + 最初と最後の値を指定 すれば、途中の状態は勝手に補完してくれるんすね。エライ。

MessageBoard.h



//
// MessageBoard.h
// CrossBacklog
//
// Created by aqubi on 10/12/05.
// Copyright 2010 aqubi. All rights reserved.
//
typedef enum {
MessageBoardTop,
MessageBoardBottom
} MessageBoardPosition;

@interface MessageBoard : UIView {
UILabel *label;
UIView *parentView;
MessageBoardPosition position;
}

@property (nonatomic, retain) UILabel *label;
@property (nonatomic, assign) MessageBoardPosition position;

+ (MessageBoard *)showMessageBoard:(UIView *)view message:(NSString *) message;
- (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context;
@end


MessageBoard.m



//
// MessageBoard.m
// CrossBacklog
//
// Created by aqubi on 10/12/05.
// Copyright 2010 aqubi. All rights reserved.
//

#import "MessageBoard.h"

@implementation MessageBoard
@synthesize label;
@synthesize position;

int height = 26;
float backgroundAlpha = 0.75f;
float radius = 10.0f;

- (id)initWithView:(UIView *) view {
if (self = [super init]) {
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
parentView = view;
CGRect rect = CGRectMake(0, - height, parentView.bounds.size.width, height);
self.frame = rect;
label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, rect.size.width, 20)];
label.adjustsFontSizeToFitWidth = NO;
label.textAlignment = UITextAlignmentCenter;
label.opaque = NO;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
position = MessageBoardBottom;
[self addSubview:label];
}
return self;
}

- (void)dealloc {
[label release];
label = nil;
[super dealloc];
}

- (void) show {
CGPoint startPoint;
if (position == MessageBoardTop) {
startPoint = CGPointMake(parentView.bounds.size.width / 2.0, - height / 2);
} else {
startPoint = CGPointMake(parentView.bounds.size.width / 2.0, parentView.bounds.size.height + height / 2);
}
CGPoint endPoint;
if (position == MessageBoardTop) {
endPoint = CGPointMake(parentView.bounds.size.width / 2.0, height / 2);
} else {
endPoint = CGPointMake(parentView.bounds.size.width / 2.0, parentView.bounds.size.height - height / 2);
}

self.center = startPoint;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(_didEndAnimation)];
self.center = endPoint;
[UIView commitAnimations];
}

- (void) _didEndAnimation {
[NSThread sleepUntilDate:[[NSDate date] addTimeInterval:2]]; //wait
CGPoint endPoint;
if (position == MessageBoardTop) {
endPoint = CGPointMake(parentView.bounds.size.width / 2.0, - height / 2);
} else {
endPoint = CGPointMake(parentView.bounds.size.width / 2.0, parentView.bounds.size.height + height / 2);
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
self.center = endPoint;
[UIView commitAnimations];
}

- (void)drawRect:(CGRect)rect {
CGRect allRect = self.bounds;
CGRect boxRect = CGRectMake(1, 0, allRect.size.width - 2, allRect.size.height - 2);
CGContextRef ctxt = UIGraphicsGetCurrentContext();
[self fillRoundedRect:boxRect inContext:ctxt];
}

- (void)fillRoundedRect:(CGRect)rect inContext:(CGContextRef)context {
CGContextBeginPath(context);
CGContextSetGrayFillColor(context, 0.0, backgroundAlpha);
CGContextMoveToPoint(context, CGRectGetMinX(rect) + radius, CGRectGetMinY(rect));
float topRadius = radius;
float bottomRadius = radius;
if (position == MessageBoardTop) {
topRadius = 0.0f;
} else if (position == MessageBoardBottom) {
bottomRadius = 0.0f;
}
CGContextAddArc(context, CGRectGetMaxX(rect) - topRadius, CGRectGetMinY(rect) + topRadius, topRadius, 3 * M_PI / 2, 0, 0);
CGContextAddArc(context, CGRectGetMaxX(rect) - bottomRadius, CGRectGetMaxY(rect) - bottomRadius, bottomRadius, 0, M_PI / 2, 0);
CGContextAddArc(context, CGRectGetMinX(rect) + bottomRadius, CGRectGetMaxY(rect) - bottomRadius, bottomRadius, M_PI / 2, M_PI, 0);
CGContextAddArc(context, CGRectGetMinX(rect) + topRadius, CGRectGetMinY(rect) + topRadius, topRadius, M_PI, 3 * M_PI / 2, 0);
CGContextClosePath(context);
CGContextFillPath(context);
}

+ (MessageBoard *)showMessageBoard:(UIView *)view message:(NSString *) message {
MessageBoard *board = [[[MessageBoard alloc] initWithView:view] autorelease];
board.label.text = message;
[view addSubview:board];
[board show];
return board;
}

@end


使うときは
[MessageBoard showMessageBoard:view message:@"メッセージ"];
で。

既にそういう便利なものがあるとか...こうした方がもっといいよ..とかあれば指摘してもらえると嬉しいです。
• • •