Ryusuke Fuda's Tech Blog

Softweare Enginier about Web, iOS, Android.

iOS cocoapods FLAnimatedImagegif を使ってgifを再生

FLAnimatedImagegifを使用(あのFlipboardが公開してるライブラリ)

■ Podでインストール
pod 'FLAnimatedImage', '~> 1.0'
■ 使いたいViewControllerに2つのヘッダファイルインポート
#import "FLAnimatedImage.h"
#import "FLAnimatedImageView.h"
ローカルのgifファイル(nyan.gif)を再生させたいとき
NSURL *gifUrl = [[NSBundle mainBundle] URLForResource:@"nyan" withExtension:@"gif"];
FLAnimatedImage *gifImage = [[FLAnimatedImage alloc] initWithAnimatedGIFData:[NSData dataWithContentsOfURL:gifUrl]];
FLAnimatedImageView *animationView = [[FLAnimatedImageView alloc] init];
animationView.animatedImage = gifImage;
self.view = animationView;
ウェブのURLにあるgifを再生させたいとき
FLAnimatedImage *gifImage = [[FLAnimatedImage alloc] initWithAnimatedGIFData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://raphaelschaad.com/static/nyan.gif"]]];
FLAnimatedImageView *animationView = [[FLAnimatedImageView alloc] init];
animationView.animatedImage = gifImage;
self.view = animationView;

たったこれだけでできる。ありがとうFlipboardさん。

参照)
https://github.com/Flipboard/FLAnimatedImage

iOS UIImagePicakerController 日本語化

UIImagePicakerControllerを使ってデフォルトのカメラを呼び出すと表示が英語になっていて、コードからいじれない。
→言語の設定をすると変更できる。


■ ビルドの言語設定
TARGETS > {PRODUCT_NAME}> Info > Localization native development region
→Japan を選択

■ プロジェクトのLocalizationsにJapanese追加
PROJECT > Info > Localizations
→ + Japanese選択
→ infoPlist.strings, main.storyboard が選択されている事を確認して Finish押す
※ storyboardのチェックが出てこない時は、一度storyboardのファイルを選択して右側のメニューをぬるっと出してそこの一番左のメニューのLocalizationのボタンを押す。
→ EnglishとJapaneseにチェックが入っていることを確認

■ Localizationのstringファイル追加
File > New > File... > Resource > Strings File
→ ファイル名は Localizable
→ Englishが選択されている状態でLocalize押す

■ ファイルをLocalizeする
→ Localizable.string を選択し右メニューのLocalizeのEnglishとJapanese両方にチェック

■ ひと通りチェック
→ Main.storyboardの下にMain.storyboard(English)とMain.storyboard(Japanese)がある
→ Localizable.stringsの下にLocalizable.strings(English)とLocalizable.strings(Japanese)がある


これでBuildするとUIImagePicakerControllerやNavigationBarなど純正のUI部分が日本語になる


参考)
http://idea-cloud.com/dev/localise.html
http://lab.dolice.net/blog/2013/04/17/xcode-localize/

iOS JASidePanelsをstoryboardで実装

nanapiのアンサーなどに使われている、サイドメニューのライブラリJASidePanelsを既存のシステムに追加実装する。

JASidePanels Github
https://github.com/gotosleep/JASidePanels

■ cocoapodsでインストール
Podfile

pod 'JASidePanels'

■ 新しいClassを追加(MySidePanelControllerという名前でやる)
File>New>File>Objective-C Class>
※Subclass of を JASidePanelController にする

■ storyboardで新しいViewControllerを作りCustom Classを"MySidePanelController"にする。
storyboardのRootView(矢印のView)をMySidePanelControllerにする。

■ 左側に出てくるViewをつくる
Storyboardで新しくViewControllerを追加し、SideViewController ClassをつくりCustom Classに設定する。

■ 今あるViewのNavigationControllerにStoryboard IDをつける
TopNavigationController とする。

■ MySidePanelControllerにコードを追加
MySidePanelController.m

-(void) awakeFromNib
{
    //SideViewControllerが左側に出てくるViewのStoryboard ID
    [self setLeftPanel:[self.storyboard instantiateViewControllerWithIdentifier:@"SideViewController"]];
    //TopNavigationControllerが真ん中のViewのStoryboard ID
    [self setCenterPanel:[self.storyboard instantiateViewControllerWithIdentifier:@"TopNavigationController"]];
    //左側のViewの幅も指定できる
    [self setLeftFixedWidth:200];
}

これでビルドすると今までのViewの左上にボタンができて押すとヒュッと左側にSideViewControllerのViewが出る。

iOS Segueを使わずにコードで画面遷移

storyboad上で線を引かずに遷移させる

■ 遷移先のstoryboadのIdentityを設定(Storyboad右側のCustom Classの下)

Storyboad ID: FavoriteViewController
Use Storyboad IDにチェックを入れる

■ 遷移させるViewControllerのヘッダーファイルimport

#import "FavoriteViewController.h"

■ ボタンのActionなどでこれを呼ぶ

FavoriteViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"FavoriteViewController"];
[self presentModalViewController:controller animated:YES]; //モーダルで呼び出す


参考)
http://somtd.hatenablog.com/entry/20120123/1327763634

ios mach-o linker error が大量に出たとき

FBtoken 的なエラーが9個くらい出たとき

■ Parseフレームワークを入れたのが原因らしい

■ 解決策
BuildSettings > Linking > Other Linker Flags の -ObjC を削除

参考)
http://stackoverflow.com/questions/15457136/parse-for-ios-errors-when-trying-to-run-the-app

EGOTableViewPullRefresh ios7実装

nanapiのアンサー, Newspicks他いろんなアプリで使われてる引っ張って更新を実装

■ Podfile

pod 'EGOTableViewPullRefresh'

■ storyboardでviewへTableViewをドラッグする。

■ TableViewを選択した状態でビヨーンとViewController.hファイルへ伸ばし、UITableViewのIBOutletをつくる

■ TableViewを選択した状態で右側のOutletsのdelegateからstoryboadのviewの黄色いとこへビヨーンと伸ばす。UITableViewはUIScrollViewを継承しているので、UIScrollViewのdelegateMethodが使える。

■ ViewController.h

#import <UIKit/UIKit.h>
#import "EGORefreshTableHeaderView.h"

@interface ViewController : UIViewController <EGORefreshTableHeaderDelegate, UITableViewDelegate, UITableViewDataSource>{
	
	EGORefreshTableHeaderView *_refreshHeaderView;
	
	//  Reloading var should really be your tableviews datasource
	//  Putting it here for demo purposes
	BOOL _reloading;
}
@property (weak, nonatomic) IBOutlet UITableView *tableview;


@end

■ ViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];


    if (_refreshHeaderView == nil) {
		
		EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - _tableview.bounds.size.height, self.view.frame.size.width, _tableview.bounds.size.height)];
		view.delegate = self;
		[self.tableview addSubview:view];
		_refreshHeaderView = view;
		
	}
	
	//  update the last update date
	[_refreshHeaderView refreshLastUpdatedDate];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
	return YES;
}


#pragma mark Data Source Loading / Reloading Methods

- (void)reloadTableViewDataSource{
	
	//  should be calling your tableviews data source model to reload
	//  put here just for demo
	_reloading = YES;
	
}

- (void)doneLoadingTableViewData{
	
	//  model should call this when its done loading
	_reloading = NO;
	[_refreshHeaderView egoRefreshScrollViewDataSourceDidFinishedLoading:_tableview];
	
}


#pragma mark UIScrollViewDelegate Methods
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
	
	[_refreshHeaderView egoRefreshScrollViewDidScroll:scrollView];
    
}


- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
	
	[_refreshHeaderView egoRefreshScrollViewDidEndDragging:scrollView];
	
}


#pragma mark EGORefreshTableHeaderDelegate Methods

- (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view{
	
	[self reloadTableViewDataSource];
	[self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:3.0];
	
}

- (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view{
	
	return _reloading; // should return if data source model is reloading
	
}

- (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view{
	
	return [NSDate date]; // should return date data source was last changed
	
}

#pragma mark Memory Management
- (void)viewDidUnload {
	_refreshHeaderView=nil;
}

- (void)dealloc {
	
	_refreshHeaderView = nil;
//    [super dealloc];
}

■ これでRunするとtableview を下へ引っ張ると動きが確認できる。
Pull down to refresh → Release to refresh → Loading

■ iOS7でめり込みを防ぐやり方はこちら参考
http://lab.4cast.co.jp/?p=1145

■ 文字やクルクルの位置をカスタムしたい時いじるファイル
Pods > EGOTableViewPullRefresh > EGORefreshTableHeaderView.m

UIRefreshControl 背景 実装

TableViewControllerがないTableViewにUIRefreshControlを実装

■ .h

@property (nonatomic, weak) UIRefreshControl *refreshControl;

■ .m

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //UIRefreshControl 初期化
    UIRefreshControl *rc = [[UIRefreshControl alloc] init];

    //引っ張ったときのaction追加   
    [rc addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];

    //tableViewにUIRefreshControl追加
    [tableView_ addSubview:rc];

    //このままだとクルクルの背景がtableviewより前にくるので、後ろへ
    [tableView_ sendSubviewToBack:rc];
    self.refreshControl = rc;

    //クルクルの後ろに背景追加
    UIImageView *rcImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed: @"refresh_bg.jpg"]];
    [self.refreshControl insertSubview:rcImageView atIndex:0];
}

- (void)handleRefresh:(id)sender
{
    処理...
    
    //クルクル終了
    [self.refreshControl endRefreshing];
}

こんな感じで背景付きでクルクル実装できる。