More Related Content Similar to iOS UI Component API Design
Similar to iOS UI Component API Design (20) iOS UI Component API Design6. カスタマイズ用の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
7. カスタマイズ用の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
8. カスタマイズ用の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
9. カスタマイズ用の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
16. @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
継承するのか?
継承より組み立てを好む
17. @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
継承するのか?
継承より組み立てを好む
18. @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
継承するのか?
継承より組み立てを好む
19. @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)
20. @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)
21. @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)
23. 継承するのか?
継承より組み立てを好む
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
24. 継承するのか?
継承より組み立てを好む
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
25. 継承するのか?
継承より組み立てを好む
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
26. 継承するのか?
継承より組み立てを好む
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
27. 継承するのか?
継承より組み立てを好む
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
28. 継承するのか?
継承より組み立てを好む
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
29. 継承するのか?
継承より組み立てを好む
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
スケールしない
37. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
38. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
39. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
40. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
41. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
42. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
43. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
44. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
45. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
46. 設定オブジェクトの一例
MDCSwipeToChoose
MDCSwipeOptions *options = [MDCSwipeOptions new];
options.delegate = self;
options.onPan = ^(MDCPanState *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];
48. options.onPan = ^(UIView *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
49. options.onPan = ^(UIView *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
50. options.onPan = ^(UIView *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
51. options.onPan = ^(UIView *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
52. options.onPan = ^(UIView *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
options.onPan = ^(MDCPanState *state){
MDCSwipeDirection direction = state.direction;
53. options.onPan = ^(UIView *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
パラメータ・オブジェクト
ブロックのシグネチャの変化を回避する
options.onPan = ^(MDCPanState *state){
MDCSwipeDirection direction = state.direction;
56. options.onPan = ^(UIView *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
options.onPan = ^(MDCPanState *state){
MDCSwipeDirection direction = state.direction;
パラメータ・オブジェクト
サポートしないパラメータを少しずつ排除
57. options.onPan = ^(UIView *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
options.onPan = ^(MDCPanState *state){
MDCSwipeDirection direction = state.direction;
パラメータ・オブジェクト
サポートしないパラメータを少しずつ排除
58. options.onPan = ^(UIView *view,
MDCSwipeDirection direction,
CGFloat thresholdRatio){
if (direction == MDCSwipeDirectionLeft) {
NSLog(@"Panning to the left...");
}
};
options.onPan = ^(MDCPanState *state){
MDCSwipeDirection direction = state.direction;
パラメータ・オブジェクト
サポートしないパラメータを少しずつ排除
60. ご参考までに
• 本日のスライド
• 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