以下のコードで、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"]);