ここでは、iOS 用の Item ユーザーコントロールを作成し、項目属性または変数のコンテンツを表示する方法について説明します。
そのため、Star Rating ユーザーコントロールを作成し、星の数のリストとして数値フィールドを表示します。これは GeneXus の SD StarRating と非常に似ています。
実行画面の外観は次のとおりです。
iOS 用ユーザーコントロールを開発するには、次の要件があります。
ユーザーコントロールには、定義と実装の 2 つのコンポーネントがあります。
定義は Web ユーザーコントロールの定義と多少異なるもののほぼ同様です。
実装では、Objective-C 言語を使って XCode でプログラムする必要があります。このページでは、皆さんが Objective-C 言語と XCode の両方に精通しているものとします。
コントロールの定義は、既存のコントロールの定義をコピーして開始できます。
次の操作を実行する必要があります。
- ユーザーコントロール名と説明を変更します: UCStarRating など。
- [ Version ] タグを初期値に設定します。
- [ Platform ] を SmartDevices に設定します。
- iOS_SupportFiles にライブラリーの名前 (例: libUCStarRating.a) でファイルを追加します。これはユーザーコントロールの実装を追加するライブラリーです。
<iOS_SupportFiles>
<File>libUCStarRating.a</File>
</iOS_SupportFiles>
- iOS_ClassName タグにメインクラスの名前を追加します (この例では、UCStarRating)。
<iOS_ClassName>UCStarRating</iOS_ClassName>
不明な場合は、Rating.control ファイルを確認してください。
- このコントロールでは、https://github.com/dlinsin/DLStarRating にある DLStarRatingControl を使用するので、そのコピーを入手します。
- 機能するように、いくつか変更を加える必要があります。
GeneXus ユーザーコントロールの内部実装と競合しないように、DLStarRatingControl クラスの名前を DLStarRatingControl2 に変更し、DLStarView クラスの名前を DLStarView2 に変更します。必ずプロジェクトをコンパイルし、内部参照を変更する必要があります (検索/置換を使用)。
次に、DLStarRatingControl2.m の -endTrackingWithTouch:withEvent: メソッドに移動し、次の行を追加します。
[ self sendActionsForControlEvents:UIControlEventValueChanged ] ;
- UCStarRating という XCode の新しい Cocoa Touch Static Library プロジェクトを作成します。
- /Users/MacUserName/Library/Artech/GeneXus にある GXFlexibleClient.framework をインポートします。
- ダウンロードした DLStarRating プロジェクトをインポートします。プロジェクトに関連付ける xcodeproj を検索し、Xcode プロジェクトの [ Groups and Files ] サイドバーのルートにドラッグ アンド ドロップします。ダイアログが表示されます。 [ Copy items ] のチェックボックスがオフになっていることと、 [ Reference Type ] が [ Relative to Project ] になっていることを確認してから、 [ Add ] をクリックします。
- 新しいクラスを作成し、UCStarRating という名前を付けます。それを GXControlEditableWithLabelSingleEditorViewBase のサブクラスにします。
- <GXFlexibleClient/GXFlexibleClient.h> をインポートします。
- 次の 2 つのプロパティを追加します: maxValue と step (両方とも int タイプ)
- UCStarRating.h ヘッダーファイルは次のようになります。
#import <Foundation/Foundation.h>
#import <GXFlexibleClient/GXFlexibleClient.h>
@interface UCStarRating : GXControlEditableWithLabelSingleEditorViewBase {
float _maxValue;
float _step;
}
@property (nonatomic, readonly) float maxValue;
@property (nonatomic, readonly) float step;
@end
- 実装ファイルに移動し、DLStarRatingControl2 タイプの starRatingControl という名前の非公開プロパティを追加します (忘れずに h ファイルをインストールしてください)。
- 「委任」プロパティを統合します。このプロパティは GXControlEditableWithLabelSingleEditorViewBase で宣言されています。このオブジェクトを使用して、コントロールの値の変更を作成者に通知します。
@synthesize maxValue = _maxValue, step = _step;
- GXControlEditableWithLabelSingleEditorViewBase 抽象メソッドを実装します。
- (UIView *)newEditorViewWithFrame:(CGRect)frame {
if ( [ self properties ] ) {
_maxValue = [ [ self properties ] getPropertyValueInteger:@"@UCStarRatingMaxValue" ] ;
_step = [ [ self properties ] getPropertyValueInteger:@"@UCStarRatingStep" ] ;
}
else {
_maxValue = 5;
_step = 1;
}
int cantStars = CalculateNumberOfStars(_maxValue, _step);
DLStarRatingControl2 *control = [ [ DLStarRatingControl2 alloc ] initWithFrame:frame andStars:cantStars isFractional:NO ] ;
control.rating = 3;
[ control setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight ] ;
[ control setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter ] ;
[ control addTarget:self action:@selector(valueChangedForControl:) forControlEvents:UIControlEventValueChanged ] ;
[ control setEnabled:self.enabled && !self.readOnly ] ;
return control;
}
- (void)valueChangedForControl:(id)sender {
if ( [ sender isEqual:self.starRatingControl ] ) {
int val = self.starRatingControl.rating * self.step;
if (val > self.maxValue)
val = self.maxValue;
id<gxentitydata> entityData = [ self entityData ] ;
if ( [ entityData conformsToProtocol:@protocol(GXMutableEntityData) ] ) {
id fieldValue = [ GXEntityHelper coreDataFieldValueFroFieldInfo: [ [ self fieldDescriptor ] entityDataFieldInfo ]
fromValue: [ NSNumber numberWithInt:val ]
] ;
[ (id<gxmutableentitydata>)entityData setValue:fieldValue forEntityDataField: [ self fieldDescriptor ] ] ;
}
}
}
#pragma mark - GXControlEditableWithLabelBase overrides
- (void)setReadOnly:(BOOL)readOnly {
[ super setReadOnly:readOnly ] ;
if ( [ self isEditorViewLoaded ] ) {
[ self.starRatingControl setEnabled:!readOnly && self.enabled ] ;
}
}
- (void)setEnabled:(BOOL)enabled {
[ super setEnabled:enabled ] ;
if ( [ self isEditorViewLoaded ] ) {
[ self.starRatingControl setEnabled:enabled && !self.readOnly ] ;
}
}
- (void)loadEntityDataFieldValue {
int value = [ self.entityDataFieldValue respondsToSelector:@selector(intValue) ] ? MAX(0, [ self.entityDataFieldValue intValue ] ) : 0;
[ self.starRatingControl setRating:CalculateNumberOfStars(value, self.step) ] ;
}
+ (BOOL)isValidForDataType:(GXDataType)dataType {
return (dataType == GXDataTypeNumeric);
}
</gxmutableentitydata></gxentitydata>
- 必要な GXControlWithLabelBase メソッドを上書きします。
- (DLStarRatingControl2 *)starRatingControl {
return (DLStarRatingControl2 *) [ self loadedEditorView ] ;
}
+ (BOOL) isValidForDataType:(GXDataType)dataType {
return (dataType == GXDataTypeNumeric);
}
- (DLStarRatingControl *) starRatingControl {
return (DLStarRatingControl *) [ super editorView ] ;
}
- CalculateNumberOfStars メソッドを定義します。
static int CalculateNumberOfStars(int value, int step) {
if (step == 0) return 0;
return (value / step) + (value % step == 0 ? 0 : 1);
}
- 使用されている画像の場所を示すためのバンドル (DLImages.bundle) を作成します。
- DLStarRatingControl2.m の次の行を:
star = [ [ UIImage imageNamed:@"star.png" ] retain ] ;
highlightedStar = [ [ UIImage imageNamed:@"star_highlighted.png" ] retain ] ;
次のように変更します:
star = [ GXUtilities imageNamed:@"star.png" inBundle:@"DLImages" ] ;
highlightedStar = [ GXUtilities imageNamed:@"star_highlighted.png" inBundle:@"DLImages" ] ;
- 必ずライブラリーをコンパイルしてください。
- 生成された libUCStarRating.a ファイルをコピーして、必要に応じてバンドルし、GeneXus ユーザーコントロールを定義します。
|