iOS UITextViewまたはUILabelで、アクションへのクリック可能なリンク [重複]。
質問
を作りたいのですが
UILabel
または
UITextView
で、その中に2つのクリック可能なリンクがあるテキストがあります。ウェブページへのリンクではありませんが、これらの2つのリンクにアクションをリンクさせたいのです。
UIButton
. 私が見たすべての例は、Webビューへのリンクですが、私はそれを望んでいない。 同様に、テキストは他の言語に翻訳されるため、位置は動的でなければなりません。
これを作りたい。
どのように解決するのですか?
私はこれとまったく同じ問題を解決する必要がありました。それは、2 つのリンクが含まれる非常に類似したテキストを複数行にわたって表示し、どの言語でも (異なる語順などを含めて) 翻訳できるようにする必要があるということです。 私はちょうどそれを解決したので、私がそれをした方法を共有させてください。
当初、私は属性付きのテキストを作成し、タップのタッチ位置をそのテキスト内の領域にマッピングすることを考えていました。それは可能だと思いますが、あまりに複雑なアプローチだとも思っています。
これは、私が代わりに行うことになったものです。
要約です。
- 英語のメッセージに非常に基本的なカスタムのマークアップを行い、さまざまな要素を解析できるようにします。
- マークアップを残して残りを翻訳するように翻訳者に指示します。
- このメッセージのコンテナとして機能する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");
}
}
これが役に立つことを願っています。これを行うにはもっとスマートでエレガントな方法があると思いますが、これは私が思いついたもので、うまく機能します。
アプリでの見え方は以下のとおりです。
幸運を祈ります。:-)
エリック
関連
-
[解決済み] 制約条件の変更をアニメーションで表現するには?
-
[解決済み] SwiftでStringを配列に分割する?
-
[解決済み] IBOutletsはARCのもとで強くなるべきか、弱くなるべきか?
-
[解決済み] UITextViewのサイズをコンテンツに合わせるには?
-
[解決済み] テキストフィールドを移動する方法(次へボタン/完了ボタン)
-
[解決済み] CocoaPodsの最新バージョンにアップデートしますか?
-
[解決済み] iOSとWatchKitで画像のtintColorを変更する方法
-
[解決済み] iPadマルチタスクのサポートには、これらの方向が必要です。
-
[解決済み] NSNotificationCenterのaddObserver in Swift
-
[解決済み】NSAttributedStringでクリック可能なリンクを作成するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
libc++abi.dylib が NSException 型の捕捉できない例外で終了する理由 エラー
-
iOSコンパイルポッドでエラー CocoaPods could not find compatible versions for pod "XXXXX" が報告される。
-
[解決済み] フレームワークを使用したiOSアプリがデバイス上でクラッシュ、dyld: ライブラリがロードされない、Xcode 6 Beta
-
[解決済み] UIViewController のビューが表示されているかどうかを確認する方法
-
[解決済み] UITextFieldのテキスト変更イベント
-
[解決済み] CocoaPodsの最新バージョンにアップデートしますか?
-
[解決済み] iOSで現在のデバイスの言語を取得するには?
-
[解決済み] コア・データ エンティティの全インスタンスを削除する最短の方法
-
[解決済み] Swift 3でディスパッチキューを作成する方法
-
[解決済み] セキュリティで保護されたWebサービスにもアクセスするiOSアプリで、Facebook認証を行うためのデザイン