詳細
さまざまな部分を解析できるように、英語のメッセージに非常に基本的なカスタム マークアップを含めます。
翻訳者にマークアップを残して残りを翻訳するように指示する
このメッセージのコンテナとして機能する UIView を用意する
英語のメッセージを細かく分割して、通常のテキストとクリック可能なテキストを分離します
ピースごとに、コンテナー UIView に UILabel を作成します。
クリック可能な部分については、スタイルを設定し、ユーザー インタラクションを許可
して、タップ ジェスチャ認識エンジンを作成します。
非常に基本的な簿記を行って、単語を
行全体に完全に配置します
理解するために。
ビュー コントローラの viewDidLoad に、次のように配置しました。
[self buildAgreeTextViewFromString:NSLocalizedString(@"I agree to the #<ts>terms of service# and #<pp>privacy policy#",
@"PLEASE NOTE: please translate \"terms of service\" and \"privacy policy\" as well, and leave the #<ts># and #<pp># around your translations just as in the English version of this message.")];
メッセージを作成するメソッドを呼び出しています。私が思いついたマークアップに注意してください。もちろん、独自のものを発明することもできますが、重要なのは、複数の単語にまたがるため、クリック可能な各領域の端もマークすることです。
メッセージをまとめる方法は次のとおりです。以下を参照してください。最初に、英語のメッセージを # 文字 (または @"#" 文字列) で分割します。そうすれば、ラベルを個別に作成する必要がある各ピースを取得できます。<ts>
それらをループして、基本的なマークアップを探し、<pp>
どの部分が何へのリンクであるかを検出します。作業しているテキストのチャンクがリンクの場合は、少しスタイルを整えて、タップ ジェスチャ認識機能をセットアップします。もちろん、マークアップ文字も取り除きます。これは本当に簡単な方法だと思います。
スペースの処理方法などの微妙な点に注意してください。(ローカライズされた) 文字列からスペースを取得するだけです。スペースがない場合 (中国語、日本語)、チャンク間にもスペースはありません。スペースがある場合、それらは必要に応じて自動的にチャンクの間隔を空けます (例: 英語の場合)。ただし、次の行の先頭に単語を配置する必要がある場合は、そのテキストから空白のプレフィックスを削除する必要があります。そうしないと、適切に配置されないためです。
- (void)buildAgreeTextViewFromString:(NSString *)localizedString
{
// 1. Split the localized string on the # sign:
NSArray *localizedStringPieces = [localizedString componentsSeparatedByString:@"#"];
// 2. Loop through all the pieces:
NSUInteger msgChunkCount = localizedStringPieces ? localizedStringPieces.count : 0;
CGPoint wordLocation = CGPointMake(0.0, 0.0);
for (NSUInteger i = 0; i < msgChunkCount; i++)
{
NSString *chunk = [localizedStringPieces objectAtIndex:i];
if ([chunk isEqualToString:@""])
{
continue; // skip this loop if the chunk is empty
}
// 3. Determine what type of word this is:
BOOL isTermsOfServiceLink = [chunk hasPrefix:@"<ts>"];
BOOL isPrivacyPolicyLink = [chunk hasPrefix:@"<pp>"];
BOOL isLink = (BOOL)(isTermsOfServiceLink || isPrivacyPolicyLink);
// 4. Create label, styling dependent on whether it's a link:
UILabel *label = [[UILabel alloc] init];
label.font = [UIFont systemFontOfSize:15.0f];
label.text = chunk;
label.userInteractionEnabled = isLink;
if (isLink)
{
label.textColor = [UIColor colorWithRed:110/255.0f green:181/255.0f blue:229/255.0f alpha:1.0];
label.highlightedTextColor = [UIColor yellowColor];
// 5. Set tap gesture for this clickable text:
SEL selectorAction = isTermsOfServiceLink ? @selector(tapOnTermsOfServiceLink:) : @selector(tapOnPrivacyPolicyLink:);
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self
action:selectorAction];
[label addGestureRecognizer:tapGesture];
// Trim the markup characters from the label:
if (isTermsOfServiceLink)
label.text = [label.text stringByReplacingOccurrencesOfString:@"<ts>" withString:@""];
if (isPrivacyPolicyLink)
label.text = [label.text stringByReplacingOccurrencesOfString:@"<pp>" withString:@""];
}
else
{
label.textColor = [UIColor whiteColor];
}
// 6. Lay out the labels so it forms a complete sentence again:
// If this word doesn't fit at end of this line, then move it to the next
// line and make sure any leading spaces are stripped off so it aligns nicely:
[label sizeToFit];
if (self.agreeTextContainerView.frame.size.width < wordLocation.x + label.bounds.size.width)
{
wordLocation.x = 0.0; // move this word all the way to the left...
wordLocation.y += label.frame.size.height; // ...on the next line
// And trim of any leading white space:
NSRange startingWhiteSpaceRange = [label.text rangeOfString:@"^\\s*"
options:NSRegularExpressionSearch];
if (startingWhiteSpaceRange.location == 0)
{
label.text = [label.text stringByReplacingCharactersInRange:startingWhiteSpaceRange
withString:@""];
[label sizeToFit];
}
}
// Set the location for this label:
label.frame = CGRectMake(wordLocation.x,
wordLocation.y,
label.frame.size.width,
label.frame.size.height);
// Show this label:
[self.agreeTextContainerView addSubview:label];
// Update the horizontal position for the next word:
wordLocation.x += label.frame.size.width;
}
}
ジェスチャーを使用する場合は、このメソッドを使用します。
- (void)tapOnTermsOfServiceLink:(UITapGestureRecognizer *)tapGesture
{
if (tapGesture.state == UIGestureRecognizerStateEnded)
{
NSLog(@"User tapped on the Terms of Service link");
}
}
- (void)tapOnPrivacyPolicyLink:(UITapGestureRecognizer *)tapGesture
{
if (tapGesture.state == UIGestureRecognizerStateEnded)
{
NSLog(@"User tapped on the Privacy Policy link");
}
}
お役に立てれば。これを行うにはもっとスマートでエレガントな方法があると確信していますが、これが私が思いついたもので、うまく機能します。
この回答は、次のスクリーンショットのような出力を表示します...しかし、この回答からアイデアを得ました。
