質問: ### 前提・実現したいこと あらかじめ複数行のテキストが入っているUITextViewのテキストに UIButtonを押すと任意の文字列を任意の場所に挿入する という動作を実現したいです。 詳しく言うと、 あらかじめ入れたテキストの行頭に文字列を挿入し、 次の行の行頭へ移動し、またボタンを押すとそこへ任意の文字を挿入し、さらに次の行頭へカーソルを移動しておく という動作です。 --- たとえば以下の文章が入っているとします。 > > *こんにちは。わたしはロイメン大学助教授のアトラと申します。* > > *年齢は45歳です。* > > *人種問題について研究しております。* > > > UIButtonを押す -> 任意の文字列「**xx行目ですよ:**」を挿入 > > **1行目ですよ:***こんにちは。わたしはロイメン大学助教授のアトラと申します。* > > *年齢は45歳です。* > > *人種問題について研究しております。* > > > もう一度ボタンを押すと、 > > **1行目ですよ:***こんにちは。わたしはロイメン大学助教授のアトラと申します。* > > **2行目ですよ:***年齢は45歳です。* > > *人種問題について研究しております。* > > > と、挿入する場所を移動した上で任意のテキストを挿入する、という動作です。 ### 補足情報 Swift3 Xcode8 ちなみに、挿入する任意の文字列はMPMusicPlayerControllerのnowPlayingItemからとってきた動的な文字列です。 カスタムキーボードで実装ができるかと思ったのですが、 カスタムキーボードはMPMusicPlayerControllerから値を持ってこられないようなので、擬似的なオリジナルキーボードとしてUIButtonを置いてテキストに挿入できたらなぁ、と思った次第です。
回答: 暫定的な回答ですが、 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")}) ``` かなり不恰好ではありますが、 挿入したい部分の前後を特定の文字列で分けて、順番に書き直していくことで任意の位置を指定するという動作になりました。