単位変換に行列を使用することは、これを行うには悪い方法です。
「基本単位」を選択します。たとえば、長さの単位を変換する場合は、基本単位としてメートルを選択します。
UnitDefinition
単位の名前と、その単位を基本単位に変換するための変換係数を保持する構造体を作成します。
typedef struct {
unsigned long long toFundamentalUnitNumerator;
unsigned long long toFundamentalUnitDenominator;
__unsafe_unretained NSString *unitName;
} UnitDefinition;
次に、サポートするユニットを保持する配列を作成します。
static UnitDefinition unitDefinitions[] = {
{ 1, 1000000, @"micron" },
{ 1, 1000, @"millimeter" },
{ 1, 100, @"centimeter" },
{ 1, 10, @"decimeter" },
{ 1, 1, @"meter" },
{ 10, 1, @"decameter" },
{ 100, 1, @"hectometer" },
{ 1000, 1, @"kilometer" },
{ 1000000, 1, @"megameter" },
{ 254, 10000, @"inch" },
{ 9144, 10000, @"yard" },
{ 160934, 100, @"mile" }
};
配列内のユニット数の定数も必要です。
#define kUnitDefinitionCount (sizeof unitDefinitions / sizeof *unitDefinitions)
UIPickerViewDataSource
これで、次のようなプロトコルを実装できます。
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return kUnitDefinitionCount;
}
UIPickerViewDelegate
そして、次のようなプロトコルを実装できます。
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return unitDefinitions[row].unitName;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
[self updateResultView];
}
そして、あなたはこのように実装することができますupdateResultView
:
- (void)updateResultView {
UnitDefinition *fromUnit = &unitDefinitions[[unitsPicker_ selectedRowInComponent:0]];
UnitDefinition *toUnit = &unitDefinitions[[unitsPicker_ selectedRowInComponent:1]];
double input = inputField_.text.doubleValue;
double result = input
* fromUnit->toFundamentalUnitNumerator
* toUnit->toFundamentalUnitDenominator
/ fromUnit->toFundamentalUnitDenominator
/ toUnit->toFundamentalUnitNumerator;
resultLabel_.text = [NSString stringWithFormat:@"%.6g", result];
}