Thursday, December 5, 2013

ローカライズでいろいろつまづいた

自分のローカライズの方法がわるかったのか、英語環境と日本語環境でのframeが同じなのに表示される場所が違うってことが起きた。

それを解決するためにはユーザーの言語環境を見ないといけないんだけど、それをifで分けたら解決できた。

    frame = self.view.frame;
    
    float version = [[[UIDevice currentDevice] systemVersion] floatValue];
    CGRect statusFrame = [[UIApplication sharedApplication]statusBarFrame];
    CGRect navFrame = self.navigationController.navigationBar.frame;
    
    // NSLocalizedStringのEnglishとJapaneseどちらが適用されるかを調べる
    NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
    NSArray *languages = [ud objectForKey:@"AppleLanguages"];

    int enIndex = [languages indexOfObject:@"en"];
    int jaIndex = [languages indexOfObject:@"ja"];
    
    float offset = (enIndex < jaIndex ? navFrame.size.height + (version < 7.0 ? 0 : statusFrame.size.height) : 0);
    
    frame = CGRectMake(0, 0, frame.size.width, frame.size.height - offset);
こんな感じにわけたら、うまく解決できた。

多分もっといい方法があると思うんだけどね。


あと、これでわかったことなんだけど、NSLocalizedStringはlanguagesで一番最初の言語に対応する文字を返す。

Tuesday, December 3, 2013

JASidePanelで左メニューが表示される際のデリゲートを作成する

左のメニューが表示されるさいに、その中のtableviewを更新したいなーと思っていたので、ごちゃごちゃやってたら出来ました。
参考にしたのは以下の二つのリンク
逆引きObjective-C for iPhoneアプリ - デリゲートを自作クラスに実装する
[iOS] Protocol – Delegateパターン | Objective-C イベント伝達 その1 « きんくまデザイン

以下、その手順です。

1. delegateプロパティをJASidePanelController.hに追加する

以下のコードをJASidePanelController.hに加えます。

@property (nonatomic, assign) id delegate;

2. プロトコルをJASidePanelController.hファイルの中で定義します

プロトコルをJASidePanelController.hファイルの中にこう定義します。
(プロトコルがなんなのかは現段階で理解できていないが、気にしない♪)

// ここまで省略

@protocol JASidePanelControlDelegate; // ここを追加しました

typedef enum _JASidePanelStyle {
    JASidePanelSingleActive = 0,
    JASidePanelMultipleActive
} JASidePanelStyle;

typedef enum _JASidePanelState {
    JASidePanelCenterVisible = 1,
    JASidePanelLeftVisible,
    JASidePanelRightVisible
} JASidePanelState;

@interface JASidePanelController : UIViewController

#pragma mark - Usage
/*
ここからずっと下まで省略
*/

// Containers for the panels.
@property (nonatomic, strong, readonly) UIView *leftPanelContainer;
@property (nonatomic, strong, readonly) UIView *rightPanelContainer;
@property (nonatomic, strong, readonly) UIView *centerPanelContainer;

@property (nonatomic, assign) id delegate; // これを追加しました

@end


/************ ここから下のコードも追加しました ************/
@protocol JASidePanelControlDelegate 

@optional
- (void) JASidePanelControl:(JASidePanelController *)controller leftMenuVisible:(UIViewController *)viewController;

@end

3. 左メニューが表示されるところでデリゲートを呼び出す。

僕はここにこう書きました。

- (void)toggleLeftPanel:(__unused id)sender {
    NSLog(@"%@", _visiblePanel);
    
    if (self.state == JASidePanelLeftVisible) {
        [self _showCenterPanel:YES bounce:NO];
    } else if (self.state == JASidePanelCenterVisible) {
        [self.delegate JASidePanelControl:self leftMenuVisible:_leftPanel]; // ここを追加
        [self _showLeftPanel:YES bounce:NO];
    }
}

4. 最後にJASidePanelControllerのサブクラスでデリゲートを設定しデリゲートメソッドを埋める

// ~省略~
- (void)viewDidLoad
{
    [super viewDidLoad];
 // Do any additional setup after loading the view.
    
    self.delegate = self;
}

// ~省略~
- (void) JASidePanelControl:(JASidePanelController *)controller leftMenuVisible:(UIViewController *)viewController {
    leftMenuViewController *leftMenu = (leftMenuViewController *)viewController;
    [leftMenu.table reloadData];
}

多分、これでこれから表示されるViewControllerのメソッドを実行できるはず。

それよりも、はてなブログってすごいな。
あっちにコードがものすごくきれいに表示される。これからあそこをメインにしようっと。

でけたーーー!!驚きです。

Monday, December 2, 2013

NavigationBarを編集する

iPhoneアプリだと上によくナビゲーションバーがありますよね。
その編集方法です。

タイトルをつける

こちらに書いてあるコードの

self.navigationItem.title = @"タイトル";

と書くと自分の望むように変えられます。

ボタンを作成する。


    UIBarButtonItem *setting = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"settings_32.png"]
                                                               style:UIBarButtonItemStylePlain
                                                              target:self
                                                              action:@selector(settingButtonTapped:)];
    self.navigationItem.rightBarButtonItem = setting;

これは画像を使ってボタンを作成する際のサンプルコード。
UIBarButtonItemを使うんだねと覚えておけば、次調べるときも時間をかけなくてすむ。

iPhoneのOSのバージョンをプログラムから取得する

こちらのスタックフローを参考にした。
http://stackoverflow.com/questions/7848766/how-can-we-programmatically-detect-which-ios-version-is-device-running-on

NSStringで

[[UIDevice currentDevice] systemVersion]
で取得できる。

iOS6で追加された「引き下げて更新」を使ってみた

iOS6で「引き下げて更新」がdefaultで用意されました。

なので、その使い方をこちらのリンクを参考に書きます。


// UITableViewが画面にあるので、そこに対応させるようにしてみました。
- (void)viewDidAppear:(BOOL)animated {
    // UITableViewControllerを作成
    UITableViewController *tableVC = [[UITableViewController alloc]init];
    tableVC.tableView = self.table;
    
    // UIRefreshControlを作成
    UIRefreshControl *refresh = [[UIRefreshControl alloc]init];
    
    [refresh addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
    
    // 作成したrefreshをtableVCにくっつける。
    tableVC.refreshControl = refresh;
}

// refreshするプログラム。
- (void)refresh:(UIRefreshControl *)refresh {
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"sample"
                                                   message:@"sample"
                                                  delegate:self
                                         cancelButtonTitle:@"OK"
                                         otherButtonTitles:nil, nil];
    [alert show];
    [refresh endRefreshing];
}


使ってみて、意外とカスタマイズ性があまりなかったので、「引き下げて更新」を使っているアプリはほかの方法を使っているのでしょう。

defaultではださいので、cocoacontrolで見つけたこちらのライブラリーも試してみます。
これも比較的すぐ出来ました。
こちらのGithubページの通りやればすぐ出来ると思うのでわざわざ記事にはしません。

JASidePanelsの使いかた

しゃれおつなアプリを使うとあるボタンを押すと左からメニューがでてくることありますよね。

そんなものを実現してくれるのがこのgotosleep / JASidePanelsです。
ほかにも同じようなことを実現してくれるライブラリはあるのでCocoa Controlで探してみるといいでしょう。

とりあえず、今回はJASidePanelsを使うということで。

1. QuartzCore.frameworkを加える。
2. 
JASidePanelController.h
JASidePanelController.m
UIViewContorller+JASidePanel.h
UIViewContorller+JASidePanel.m
をプロジェクトに加える。
3. 
JASidePanelControllerを継承する適当なクラスをつくる。
ここではmySidePanelViewControllerと名付ける。
4.
そして作成したmySidePanelContorllerクラスのmySidePanelViewContorller.mに以下のコードを加える。

-(void)awakeFromNib{
    [self setLeftPanel:[self.storyboard instantiateViewControllerWithIdentifier:@"leftMenu"]];
    [self setCenterPanel:[self.storyboard instantiateViewControllerWithIdentifier:@"center"]];
    
    [self setLeftFixedWidth:200];
}

storyboard上で「leftMenu」と名付けられたViewControllerが左に表示される画面。
storyboard上で「center」と名付けられたViewControllerが中央に表示される画面。

※ここでstoryboardでcenterと名付ける画面をNavigation Controllerにすると、ライブラリ側で左上にメニューの画像をおいてくれます!

ただ、左のメニューから真ん中のViewControllerに値を渡す方法がないので僕は渡したい値をNSUserDefaultを使用してます。

これだけで出来ます。

Sunday, November 24, 2013

画像をアプリ内に保存 / 取り出し

画像を保存する

画像をurlにわざわざ取りにいくのは時間もかかるしめんどくさいので、アプリ内に保存してしまいましょう。
LINEとかはそうしてますよね。オフラインでも友達の写真は表示されるのでわかります。

以下のコードでOK→(参照もと: http://fitss.jp/blog/2013/05/xcodeImagePicker.shtml)


            UIImage *image = self.image.image;
            NSData *imageData = UIImagePNGRepresentation(image);
            NSString *path = [NSString stringWithFormat:@"%@/image.png", [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]];
            if ([imageData writeToFile:path atomically:YES]) {
               NSLog(@"save successs");
            } else {
                UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"エラー"
                                                               message:@"画像が保存できませんでした。あとでもう一度お試しください"
                                                              delegate:self
                                                     cancelButtonTitle:@"確認"
                                                     otherButtonTitles:nil, nil];
                [alert show];
                return;

            }



そしてこちらが保存した写真を取り出す方法

画像を取り出す

NSData *imageData = [NSData dataWithContentsOfFile:[imageLinks objectAtIndex:i]];
UIImage *image = [[UIImage alloc]initWithData: imageData];