[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
SlideShare a Scribd company logo
UIコンポーネントAPIデザイン
「パラメータ・オブジェクト」パターン
Brian Gesiak
2014年4月9日
Research Student, The University of Tokyo
@modocache #potatotips
内容
• 課題:カスタマイズ用のAPIをどう提供するか
• 細かいところまでカスタマイズしたい
• 継承より組み立てを好む
• 解決策:設定オブジェクト
• 設定オブジェクト
!
• 課題:コールバックのAPI
• ブロックやdelegateメソッドのパラメータが確定し
てしまうとなかなか変えられない
• 解決策:パラメータ・オブジェクト
カスタマイズ用のAPIの一例
JVFloatLabeledTextField
カスタマイズ用のAPIの一例
JVFloatLabeledTextField
カスタマイズ用のAPIの一例
JVFloatLabeledTextField
カスタマイズ用のAPIの一例
JVFloatLabeledTextField
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
カスタマイズ用のAPIの一例
JVFloatLabeledTextField
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
カスタマイズ用のAPIの一例
JVFloatLabeledTextField
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
カスタマイズ用のAPIの一例
JVFloatLabeledTextField
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
継承するのか?
継承より組み立てを好む
継承するのか?
• JVFloatLabeledTextFieldはUITextFieldのサブクラス
継承より組み立てを好む
継承するのか?
• JVFloatLabeledTextFieldはUITextFieldのサブクラス
• 機能がほしければこのクラスを使うしかない
継承より組み立てを好む
継承するのか?
• JVFloatLabeledTextFieldはUITextFieldのサブクラス
• 機能がほしければこのクラスを使うしかない
• 機能を追加したければサブクラスを新たに定義す
るしかない
継承より組み立てを好む
継承するのか?
• JVFloatLabeledTextFieldはUITextFieldのサブクラス
• 機能がほしければこのクラスを使うしかない
• 機能を追加したければサブクラスを新たに定義す
るしかない
• JVFloatLabeledTextFieldは継承ヒエラルキーに自分
をねじ込んでいる
継承より組み立てを好む
継承するのか?
• JVFloatLabeledTextFieldはUITextFieldのサブクラス
• 機能がほしければこのクラスを使うしかない
• 機能を追加したければサブクラスを新たに定義す
るしかない
• JVFloatLabeledTextFieldは継承ヒエラルキーに自分
をねじ込んでいる
継承より組み立てを好む
• カテゴリーだったら、どのUITextFieldでも使える
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
継承するのか?
継承より組み立てを好む
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
継承するのか?
継承より組み立てを好む
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
継承するのか?
継承より組み立てを好む
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
継承するのか?
継承より組み立てを好む
@interface UITextField (JVFloatLabeledTextField)
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
継承するのか?
継承より組み立てを好む
@interface UITextField (JVFloatLabeledTextField)
@interface JVFloatLabeledTextField : UITextField
!
@property (nonatomic, strong)
NSNumber *floatingLabelYPadding UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIFont *floatingLabelFont UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, strong)
UIColor *floatingLabelActiveTextColor UI_APPEARANCE_SELECTOR;
@property (nonatomic, assign)
NSInteger animateEvenIfNotFirstResponder UI_APPEARANCE_SELECTOR;
!
@end
継承するのか?
継承より組み立てを好む
objc_setAssociatedObject
@interface UITextField (JVFloatLabeledTextField)
継承するのか?
継承より組み立てを好む
継承するのか?
継承より組み立てを好む
static void *JVFloatingLabelYPaddingKey =
&JVFloatingLabelYPaddingKey;
!
- (void)setFloatingLabelYPadding:(NSNumber *)floatingLabelYPadding {
objc_setAssociatedObject(self,
JVFloatingLabelYPaddingKey,
floatingLabelYPadding,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
!
- (NSNumber *)floatingLabelYPadding {
return objc_getAssociatedObject(self,
JVFloatingLabelYPaddingKey);
}
!
/// Add custom setters and getters for all properties
継承するのか?
継承より組み立てを好む
static void *JVFloatingLabelYPaddingKey =
&JVFloatingLabelYPaddingKey;
!
- (void)setFloatingLabelYPadding:(NSNumber *)floatingLabelYPadding {
objc_setAssociatedObject(self,
JVFloatingLabelYPaddingKey,
floatingLabelYPadding,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
!
- (NSNumber *)floatingLabelYPadding {
return objc_getAssociatedObject(self,
JVFloatingLabelYPaddingKey);
}
!
/// Add custom setters and getters for all properties
継承するのか?
継承より組み立てを好む
static void *JVFloatingLabelYPaddingKey =
&JVFloatingLabelYPaddingKey;
!
- (void)setFloatingLabelYPadding:(NSNumber *)floatingLabelYPadding {
objc_setAssociatedObject(self,
JVFloatingLabelYPaddingKey,
floatingLabelYPadding,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
!
- (NSNumber *)floatingLabelYPadding {
return objc_getAssociatedObject(self,
JVFloatingLabelYPaddingKey);
}
!
/// Add custom setters and getters for all properties
継承するのか?
継承より組み立てを好む
static void *JVFloatingLabelYPaddingKey =
&JVFloatingLabelYPaddingKey;
!
- (void)setFloatingLabelYPadding:(NSNumber *)floatingLabelYPadding {
objc_setAssociatedObject(self,
JVFloatingLabelYPaddingKey,
floatingLabelYPadding,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
!
- (NSNumber *)floatingLabelYPadding {
return objc_getAssociatedObject(self,
JVFloatingLabelYPaddingKey);
}
!
/// Add custom setters and getters for all properties
継承するのか?
継承より組み立てを好む
static void *JVFloatingLabelYPaddingKey =
&JVFloatingLabelYPaddingKey;
!
- (void)setFloatingLabelYPadding:(NSNumber *)floatingLabelYPadding {
objc_setAssociatedObject(self,
JVFloatingLabelYPaddingKey,
floatingLabelYPadding,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
!
- (NSNumber *)floatingLabelYPadding {
return objc_getAssociatedObject(self,
JVFloatingLabelYPaddingKey);
}
!
/// Add custom setters and getters for all properties
継承するのか?
継承より組み立てを好む
static void *JVFloatingLabelYPaddingKey =
&JVFloatingLabelYPaddingKey;
!
- (void)setFloatingLabelYPadding:(NSNumber *)floatingLabelYPadding {
objc_setAssociatedObject(self,
JVFloatingLabelYPaddingKey,
floatingLabelYPadding,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
!
- (NSNumber *)floatingLabelYPadding {
return objc_getAssociatedObject(self,
JVFloatingLabelYPaddingKey);
}
!
/// Add custom setters and getters for all properties
継承するのか?
継承より組み立てを好む
static void *JVFloatingLabelYPaddingKey =
&JVFloatingLabelYPaddingKey;
!
- (void)setFloatingLabelYPadding:(NSNumber *)floatingLabelYPadding {
objc_setAssociatedObject(self,
JVFloatingLabelYPaddingKey,
floatingLabelYPadding,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
!
- (NSNumber *)floatingLabelYPadding {
return objc_getAssociatedObject(self,
JVFloatingLabelYPaddingKey);
}
!
/// Add custom setters and getters for all properties
スケールしない
設定オブジェクト
カスタマイズ用のパラメータを束ねる
設定オブジェクト
カスタマイズ用のパラメータを束ねる
設定オブジェクト
カスタマイズ用のパラメータを束ねる
設定オブジェクト
カスタマイズ用のパラメータを束ねる
設定オブジェクト
カスタマイズ用のパラメータを束ねる
設定オブジェクトの一例
MDCSwipeToChoose
設定オブジェクトの一例
MDCSwipeToChoose
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options. *state){
switch (state.direction) {
case MDCSwipeDirectionLeft:
self.webView.alpha = 0.5f - state.thresholdRatio;
break;
case MDCSwipeDirectionRight:
self.webView.alpha = 0.5f + state.thresholdRatio;
break;
case MDCSwipeDirectionNone:
self.webView.alpha = 0.5f;
break;
}
};
!
[self.webView mdc_swipeToChooseSetup:options];
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
options. *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
options. *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
options. *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
options. *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
options. *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
options. *state){
MDCSwipeDirection direction = state.direction;
options. *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
options. *state){
MDCSwipeDirection direction = state.direction;
パラメータ・オブジェクト
APIの微調整、バージョニングが可能
@interface MDCPanState : NSObject
!
@property (nonatomic, strong)
UIView *view;
@property (nonatomic, assign)
MDCSwipeDirection direction;
@property (nonatomic, assign)
CGFloat thresholdRatio;
!
@end
パラメータ・オブジェクト
APIの微調整、バージョニングが可能
@interface MDCPanState : NSObject
!
@property (nonatomic, strong)
UIView *view;
@property (nonatomic, assign)
MDCSwipeDirection direction;
@property (nonatomic, assign)
CGFloat thresholdRatio;
!
@end
DEPRECATED_ATTRIBUTE;
options. *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
options. *state){
MDCSwipeDirection direction = state.direction;
パラメータ・オブジェクト
サポートしないパラメータを少しずつ排除
options. *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
options. *state){
MDCSwipeDirection direction = state.direction;
パラメータ・オブジェクト
サポートしないパラメータを少しずつ排除
options. *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
options. *state){
MDCSwipeDirection direction = state.direction;
パラメータ・オブジェクト
サポートしないパラメータを少しずつ排除
要約
• 継承に頼らないUIコンポーネントを好む
• 設定オブジェクトで、クリーンなカスタマイズ用の
APIを提供できる
• パラメータ・オブジェクトというデザイン・パター
ンは、シグネチャの変化を未然に防ぐ
• 特にブロックのパラメータに有用
ご参考までに
• 本日のスライド
• http://modocache.io/ios-ui-component-api-design
• ぜひフォローして下さい
• Twitter: @modocache
• GitHub: https://github.com/modocache
• JVFloatLabeledTextField
• https://github.com/jverdi/JVFloatLabeledTextField
• MDCSwipeToChoose(おいらに☆を!)
• https://github.com/modocache/MDCSwipeToChoose
• 「パラメータ・オブジェクト」デザイン・パターン(英語)
• http://c2.com/cgi/wiki?ParameterObject

More Related Content

Viewers also liked (11)

PDF
RSpec 3.0: Under the Covers
Brian Gesiak
 
PDF
Intel® Xeon® Phi Coprocessor High Performance Programming
Brian Gesiak
 
PDF
Apple Templates Considered Harmful
Brian Gesiak
 
PDF
やはりお前らのCore Dataの使い方も間違っている
今城 善矩
 
PDF
Company Scouter
Shuichi Tsutsumi
 
PDF
iOS Behavior-Driven Development
Brian Gesiak
 
PDF
StoryboardでUIを使いまわす
Masaki Fuke
 
PDF
UIKit DynamicsとCoreMotionを組み合わせて物体を転がしてみた
Kosuke Ogawa
 
PDF
アップルのテンプレートは有害と考えられる
Brian Gesiak
 
PDF
iOSビヘイビア駆動開発
Brian Gesiak
 
PPTX
技術選択とアーキテクトの役割
Toru Yamaguchi
 
RSpec 3.0: Under the Covers
Brian Gesiak
 
Intel® Xeon® Phi Coprocessor High Performance Programming
Brian Gesiak
 
Apple Templates Considered Harmful
Brian Gesiak
 
やはりお前らのCore Dataの使い方も間違っている
今城 善矩
 
Company Scouter
Shuichi Tsutsumi
 
iOS Behavior-Driven Development
Brian Gesiak
 
StoryboardでUIを使いまわす
Masaki Fuke
 
UIKit DynamicsとCoreMotionを組み合わせて物体を転がしてみた
Kosuke Ogawa
 
アップルのテンプレートは有害と考えられる
Brian Gesiak
 
iOSビヘイビア駆動開発
Brian Gesiak
 
技術選択とアーキテクトの役割
Toru Yamaguchi
 

Similar to iOS UI Component API Design (20)

PDF
I phoneアプリ入門 第5回
Sachiko Kajishima
 
PDF
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
聡 中川
 
PDF
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ
聡 中川
 
PDF
UICollectionViewLayoutでカバーフローを作りたい!
sawat1203
 
PDF
iPhone, iPad アプリ開発勉強会#3
Hiroe Orz
 
KEY
1.29.user,user,user
Tonny Xu
 
KEY
Blocksの活用法
Hidetoshi Mori
 
PDF
⑭iPhoneアプリを作ってみよう!(超初心者向け)その2
Nishida Kansuke
 
KEY
Core Graphicsでつくる自作UIコンポーネント入門
cocopon
 
PDF
Ib資料20090222
Hiroyuki Fujikawa
 
PDF
Storyboard
Hidetoshi Mori
 
PDF
Saitama beginner tips50
Tomohiko Okita
 
PDF
UITableViewで無限CoverFlowを作る
Hidetoshi Mori
 
PDF
UITableViewについて
teencoders
 
PPTX
2012 05-19第44回cocoa勉強会発表資料
OCHI Shuji
 
KEY
Cocoa勉強会201208
Satoshi Oomori
 
PDF
Swift 3 を書くときに知っておきたい API デザインガイドライン #love_swift #akibaswift
Tomohiro Kumagai
 
PDF
flasherがはじめてiOS開発をしてみて
佐藤 俊太郎
 
KEY
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
Makoto Setoh
 
PDF
I phoneアプリ入門 第4回
Sachiko Kajishima
 
I phoneアプリ入門 第5回
Sachiko Kajishima
 
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
聡 中川
 
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ
聡 中川
 
UICollectionViewLayoutでカバーフローを作りたい!
sawat1203
 
iPhone, iPad アプリ開発勉強会#3
Hiroe Orz
 
1.29.user,user,user
Tonny Xu
 
Blocksの活用法
Hidetoshi Mori
 
⑭iPhoneアプリを作ってみよう!(超初心者向け)その2
Nishida Kansuke
 
Core Graphicsでつくる自作UIコンポーネント入門
cocopon
 
Ib資料20090222
Hiroyuki Fujikawa
 
Storyboard
Hidetoshi Mori
 
Saitama beginner tips50
Tomohiko Okita
 
UITableViewで無限CoverFlowを作る
Hidetoshi Mori
 
UITableViewについて
teencoders
 
2012 05-19第44回cocoa勉強会発表資料
OCHI Shuji
 
Cocoa勉強会201208
Satoshi Oomori
 
Swift 3 を書くときに知っておきたい API デザインガイドライン #love_swift #akibaswift
Tomohiro Kumagai
 
flasherがはじめてiOS開発をしてみて
佐藤 俊太郎
 
軽量EvernoteクライアントSmartEverにおけるアプリ高速化の工夫と課題
Makoto Setoh
 
I phoneアプリ入門 第4回
Sachiko Kajishima
 
Ad

Recently uploaded (7)

PDF
20250711JIMUC総会_先進IT運用管理分科会Connpass公開資料.pdf
ChikakoInami1
 
PDF
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
PDF
20250711_日本IBM ミドルウエア・ユーザー研究会(JIMUC)総会_中村会長資料.pdf
ChikakoInami1
 
PPTX
Devcontainerのススメ(1)-Devcontainerとはどういう技術?-
iPride Co., Ltd.
 
PDF
20250711JIMUC総会IBM Automation_Platform最新情報_Connpass公開版.pdf
ChikakoInami1
 
PDF
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
PDF
20250717_Devin×GitHubCopilotで10人分の仕事は出来るのか?.pdf
Masaki Yamakawa
 
20250711JIMUC総会_先進IT運用管理分科会Connpass公開資料.pdf
ChikakoInami1
 
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
20250711_日本IBM ミドルウエア・ユーザー研究会(JIMUC)総会_中村会長資料.pdf
ChikakoInami1
 
Devcontainerのススメ(1)-Devcontainerとはどういう技術?-
iPride Co., Ltd.
 
20250711JIMUC総会IBM Automation_Platform最新情報_Connpass公開版.pdf
ChikakoInami1
 
[Hardening Designers Confernece 2025]ランサムウェアでの見えざるログ・見えるログ
kataware
 
20250717_Devin×GitHubCopilotで10人分の仕事は出来るのか?.pdf
Masaki Yamakawa
 
Ad

iOS UI Component API Design