以下のコードで、UINavigationBarを隠したり、表示させたりすることができます。
self.navigationController.navigationBarHidden = NO;
以下のコードで、UINavigationBarを隠したり、表示させたりすることができます。
self.navigationController.navigationBarHidden = NO;
アプリでよくあるUIで、ボタンをタップすると、画面外から横スライドして表示されるメニューを実装したいと思います。
今回はスライドしたメニューが画面に被さるように表示させてみます。
まず、スライドさせるビューをつくります。
今回はただのViewを使いますが、UITableViewの方がいいかと思います。
RightSlideMenuView.h
@interface RightSlideMenuView : UIView @end
RightSlideMenuView.m
@implementation RightSlideMenuView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.frame = CGRectMake( [UIScreen mainScreen].bounds.size.width, 0, 160, 568);
self.backgroundColor = [UIColor yellowCollor];
UILabel* title = [[UILabel alloc] initWithFrame:CGRectMake(30, 100, 100, 100)];
title.text = @"スライドメニューが表示されました";
title.backgroundColor = [UIColor clearColor];
}
return self;
}
次に、メニューを表示させたいViewControllerをつくります。
#import "RightSlideMenuView.h"
@interface MainViewController ()
{
RightSlideMenuView* sideMenuView_;
UIView* viewForClosingSideMenu_;
}
- (void)viewDidLoad
{
[super viewDidLoad];
sideMenuView_ = [[RightSlideMenuView alloc] initWithFrame: self.view.frame];
[self.view addSubview: sideMenuView_];
}
//スライドさせてメニューを表示させる
- (IBAction)showSideMenu:(id)sender
{
// show side menu with animation
CGRect sideMenuFrame = sideMenuView_.frame;
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseIn
animations:^{
// アニメーションをする処理
sideMenuView_.frame = CGRectMake( insideSideMenuX,
sideMenuFrame.origin.y,
sideMenuFrame.size.width,
sideMenuFrame.size.height);
} completion:^(BOOL finished) {
// アニメーションが終わった後実行する処理
}];
// メニュー外をタップしたら、メニューを閉じるようにする
// そのためのUIViewをメニュー外に設置し、これをタップしたらメニューを閉じるようにする
if (!viewForClosingSideMenu_)
{
viewForClosingSideMenu_ = [[UIView alloc] initWithFrame:
CGRectMake(0,
0,
self.view.frame.size.width
- sideMenuFrame.size.width,
self.view.frame.size.height)];
viewForClosingSideMenu_.backgroundColor = [UIColor clearColor];
UITapGestureRecognizer *closeSideMenuTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(closeSideMenu:)];
[viewForClosingSideMenu_ addGestureRecognizer:closeSideMenuTap];
[self.view addSubview: viewForClosingSideMenu_];
}
}
//メニュー外をタップしたときに呼び出されるメソッド
-(void)closeSideMenu:(int)destination
{
CGRect sideMenuFrame = sideMenuView_.frame;
[UIView animateWithDuration:0.3f
delay:0.0f
options:UIViewAnimationOptionCurveEaseIn
animations:^{
// アニメーションをする処理
sideMenuView_.frame = CGRectMake( outsideSideMenuX,
sideMenuFrame.origin.y,
sideMenuFrame.size.width,
sideMenuFrame.size.height);
} completion:^(BOOL finished) {
// アニメーションが終わった後実行する処理
}];
// メニューを閉じるためのUIViewを削除
if (viewForClosingSideMenu_)
{
[viewForClosingSideMenu_ removeFromSuperview];
viewForClosingSideMenu_ = nil;
}
}
【サンプルコードあり】URLから画像を非同期に取得するの続きです。
前回は、URLから画像をとってきてローディングさせるためのUIImageViewの専用サブクラス、LoadingImageViewを作りました。
次に他クラスで、LoadingImageViewを使って、非同期にURLから画像を取得、表示させる方法です。
また、ローディング中は画像が表示される場所にインジケータアニメーション画像が表示されます。
まず、StoryBoardで、UIImageViewを置き、そのオブジェクトのクラスをLoadingImageViewクラスに変更します。
Sample.h
#import "LoadingImageView.h" @interface Sample : UIViewController @property (retain, nonatomic) LoadingImageView *loadingImageView;
Sample.m
_loadingImageView.imageUrl = [NSURL URLWithString: imageURLStr]; [_loadingImageView startLoadImage];
プロパティのimageUrlに、画像のURLをセットします。
次に、startLoadImageメソッドで、画像を非同期で取得してきます。
その際、画像が取得、表示されるまでシンジケータが表示されます。
今回はmmasashi にお世話になりました。
参考にしてください。
http://d.hatena.ne.jp/mmasashi/20110924/1316940621
画像をURLから取得するとき、非同期で行うようにしたいとおもいます。
まず、専用のImageViewのサブクラスをつくります。
LoadingImageView.h
@interface LoadingImageView : UIImageView - (id)initWithFrame:(CGRect)frame withUrl:(NSURL *)url; // Start load the image of the specified url. // Doesn't load the image if an image has been already set. - (void)startLoadImage; // Reload load the image of the specified url. // Load the image even if a connection was already created. - (void)reloadImage; // Cancel loading if requesting. - (void)cancelLoading; // Set the url of the image to reqeust. @property (nonatomic, retain) NSURL *imageUrl; @end
LoadingImageView.m
#import "LoadingImageView.h"
typedef enum LazyImageViewTag_ {
LazyImageViewTagIndicatorView = 1,
} LazyImageViewTag;
@interface LoadingImageView ()
- (void)setLoadingImage;
- (void)setLoadErrorImage;
@property (nonatomic, retain) NSURLConnection *connection;
@property (nonatomic, retain) NSMutableData *imgData;
@end
@implementation LoadingImageView
- (id)initWithFrame:(CGRect)frame withUrl:(NSURL *)url
{
self = [super initWithFrame:frame];
if (self) {
[self setImageUrl:url];
}
return self;
}
- (void)startLoadImage
{
if (self.image) return;
if (self.connection)
{
[self.connection cancel];
}
[self setImgData:[NSMutableData data]];
NSURLRequest *req = [NSURLRequest requestWithURL:self.imageUrl];
NSURLConnection *con = [NSURLConnection connectionWithRequest:req delegate:self];
[self setConnection:con];
[self setLoadingImage];
}
- (void)reloadImage
{
[self setImage:nil];
[self startLoadImage];
}
- (void)cancelLoading {
[self.connection cancel];
[self setConnection:nil];
if (self.image == nil) {
[self setLoadErrorImage];
}
}
#pragma mark - NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.imgData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[self setLoadErrorImage];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
UIActivityIndicatorView *iv = (UIActivityIndicatorView *)
[self viewWithTag:LazyImageViewTagIndicatorView];
if (iv) [iv removeFromSuperview];
[self setImage:[UIImage imageWithData:self.imgData]];
}
#pragma mark -
- (void)setLoadingImage
{
UIActivityIndicatorView *iv = (UIActivityIndicatorView *)
[self viewWithTag:LazyImageViewTagIndicatorView];
if (iv == nil)
{
iv = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
// [iv setCenter:CGPointMake(self.frame.size.width/2, self.frame.size.height/2)];
[iv setTag:LazyImageViewTagIndicatorView];
[self addSubview:iv];
}
iv.frame = self.frame;
iv.center = self.center;
[iv startAnimating];
[iv setHidden:NO];
//[self setBackgroundColor:[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.3]];
[self setBackgroundColor:[UIColor clearColor]];
}
- (void)setLoadErrorImage
{
UIActivityIndicatorView *iv = (UIActivityIndicatorView *)
[self viewWithTag:LazyImageViewTagIndicatorView];
[iv removeFromSuperview];
[self setImage:nil];
//[self setBackgroundColor:[UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:0.4]];
[self setBackgroundColor:[UIColor blackColor]];
}
#pragma mark -
- (void)dealloc
{
[self setImageUrl:nil];
[self.connection cancel];
[self setConnection:nil];
[self setImgData:nil];
}
@synthesize imageUrl;
@synthesize connection;
@synthesize imgData;
@end
今回はmmasashi にお世話になりました。
参考にしてください。
http://d.hatena.ne.jp/mmasashi/20110924/1316940621
続きは、【サンプルコードあり】URLから画像を非同期に取得する2です。
他クラスからLoadingImageViewを使う方法です。
NSDictionaryを含むNSArrayを、NSDictionaryの特定のキーでソートしたい時があるかと思います。
例えば、NSDctionaryの数値が値になる「English」というキーで配列をソートしてみます。
誰が英語の点数が良かったかを出力しようかと思います。
まず、教科ごとの点数と名前を持つNSDictionaryの配列を用意
NSDictionary* yamachan = [[NSDictionary alloc] initWithObjects: @[@"山ちゃん", @"80", @"30"]
forKeys: @[@"Name", @"English", @"Mathmatics"]];
NSDictionary* okamato = [[NSDictionary alloc] initWithObjects: @[@"岡本", @"67", @"60"]
forKeys: @[@"Name", @"English", @"Mathmatics"]];
NSDictionary* yamane = [[NSDictionary alloc] initWithObjects: @[@"山根", @"40", @"20"]
forKeys: @[@"Name", @"English", @"Mathmatics"]];
NSArray* students = @[yamachan, okamato, yamane];
次にこの配列を英語の点数順にソートします。
NSArray* sorted_students = [students sortedArrayUsingFunction:compareFloat context:NULL];
ソートするには、「sortedArrayUsingFunction: context:」がキモ。
第1引数は、比較を行うためのC言語の関数を定義
第2引数は、第1引数で指定した関数の引数を定義
比較を行う関数は以下です。
NSComparisonResult compareFloat(id value1, id value2, void *context)
{
float floatValue1 = [(NSNumber*)[value1 valueForKey: @"English"] floatValue];
float floatValue2 = [(NSNumber*)[value2 valueForKey: @"English"] floatValue];
if(floatValue1 > floatValue2){
return NSOrderedDescending;
}else if(floatValue1 < floatValue2){
return NSOrderedAscending;
}else{
return NSOrderedSame;
}
}
あとは配列を出力するだけ。
NSDictionary* top = [sorted_students objectAtIndex: 0];
NSLog(@"一番英語の点数が良かったのは、%@です。", [top valueForKey:@"Name"]);