質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.75%

  • Swift

    6706questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • Swift 2

    1325questions

    Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Swift3 UITextViewにボタンで文字列を挿入

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 318

mitci

score 28

前提・実現したいこと

あらかじめ複数行のテキストが入っているUITextViewのテキストに
UIButtonを押すと任意の文字列を任意の場所に挿入する
という動作を実現したいです。

詳しく言うと、
あらかじめ入れたテキストの行頭に文字列を挿入し、
次の行の行頭へ移動し、またボタンを押すとそこへ任意の文字を挿入し、さらに次の行頭へカーソルを移動しておく
という動作です。


たとえば以下の文章が入っているとします。

こんにちは。わたしはロイメン大学助教授のアトラと申します。
年齢は45歳です。
人種問題について研究しております。

UIButtonを押す -> 任意の文字列「xx行目ですよ:」を挿入

1行目ですよ:こんにちは。わたしはロイメン大学助教授のアトラと申します。
年齢は45歳です。
人種問題について研究しております。

もう一度ボタンを押すと、

1行目ですよ:こんにちは。わたしはロイメン大学助教授のアトラと申します。
2行目ですよ:年齢は45歳です。
人種問題について研究しております。

と、挿入する場所を移動した上で任意のテキストを挿入する、という動作です。

補足情報

Swift3 Xcode8
ちなみに、挿入する任意の文字列はMPMusicPlayerControllerのnowPlayingItemからとってきた動的な文字列です。
カスタムキーボードで実装ができるかと思ったのですが、
カスタムキーボードはMPMusicPlayerControllerから値を持ってこられないようなので、擬似的なオリジナルキーボードとしてUIButtonを置いてテキストに挿入できたらなぁ、と思った次第です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Stripe

    2017/09/16 23:22

    行の先頭は複数あります。ボタンを押したときにどこの行頭に挿入するのか、その定義があいまいだとコードは書けません。

    キャンセル

  • mitci

    2017/09/16 23:28

    テキストを挿入したらその行の次の行の一文字目の手前(Macでいうと↓キーで次の行に移動し、command + ←を押して一文字目の手前にカーソルを合わせたという感じ)です。

    キャンセル

  • mitci

    2017/09/16 23:33

    まずUIButtonを押す -> 一行目の一文字目の手前にテキストを挿入 -> 自動でMacでいうところの「↓」キー、「command + ←」を実行 -> またUIButtonを押す -> テキストを挿入&「↓」キー「command + ←」 -> UIButtonを押す…の繰り返しになります

    キャンセル

回答 1

check解決した方法

0

暫定的な回答ですが、
UITextViewに入っている文章を行ごとに配列に入れて、
すでに「x行目ですよ:」が挿入されている行の文章のみの配列(firstTextAry)をつくり、その数を保持したうえでその配列の全要素(全行)に改行を付け足してUITextView(この場合、testTextView)に表示させる。
そのあと、UIButtonで挿入したかった文字列を入れたあと、
「x行目ですよ:」がまだ挿入されていない行の配列をsuffixで割り出してからsliceArray型をArray型に.mapしてから、やはり改行を付与しつつtestTextViewに挿入する。

    currentTextStr = testTextView.text
    testTextView.text = ""
    textAry = textStr.components(separatedBy: CharacterSet.newlines)
    firstTextAry = textAry.filter({$0.contains("行目ですよ")})
    firstAryCount = firstTextAry.count
    firstTextAry.forEach({testTextView.insertText("\($0)\n")})

    testTextView.insertText(lineNumber)

    textAry = textStr.components(separatedBy: CharacterSet.newlines)
    secondAryCount = textAry.count - firstAryCount
    secondTextAry = textAry.suffix(secondAryCount)
    secondTextAryTrue = secondTextAry.map({$0})
    secondTextAryTrue.forEach({testTextView.insertText("\($0)\n")})

かなり不恰好ではありますが、
挿入したい部分の前後を特定の文字列で分けて、順番に書き直していくことで任意の位置を指定するという動作になりました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Swift

    6706questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • Swift 2

    1325questions

    Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。