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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Swift

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

Q&A

解決済

1回答

2168閲覧

textViewにおいてボタンをタップしたらカーソルの左の文字を1字選択するコード

Tomzy

総合スコア104

Swift

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

0グッド

0クリップ

投稿2017/11/16 09:36

###やりたいこと

textViewにおいてボタンをタップしたらカーソルの左の文字を1字選択することです。

###参照した英文サイト
リンク内容
###やったこと

ボタンをタップしたら全選択をするのは自己解決できました。
コードは下記のとおりです。

@IBAction func sentaku01(_ sender: Any) { InputView.selectAll(nil) InputView.selectAll(self) func textViewDidBeginEditing(InputView: UITextView) { DispatchQueue.main.async { InputView.selectAll(nil) print("ここまで来た14") } } }

###試したこと
上記の英文サイトを参照して下記のコードを書きましたがエラーが
でて行き詰まりました。

//←選択を押した時⇒左側を選択する @IBAction func sentaku02(_ sender: Any) { // only if there is a currently selected range if let selectedRange = InputView.selectedTextRange { // and only if the new position is valid if let newPosition = InputView.positionFromPosition(selectedRange.start, inDirection: UITextLayoutDirection.Left, offset: 1) { //set the newPosition InputView.selectedTextRange = InputView.textRangeFromPosition(newPosition, toPosition: newPosition) } }

###エラー
Value of type 'UITextView' has no member 'positionFromPosition'

###エラーのでた場所

イメージ説明ジ説明](a6296d2c09011f484df6d53dfed3d292.png)

###ご参考事項

  • 環境は下記のとおりです。

MacBook Pro (15-inch, 2016)
High Sierra OS10.13
Version 9.1 (9B55)Swift4にバージョンアップしました。

  • 下記のように定義しています。

@IBOutlet weak var InputView: UITextView!
@IBOutlet weak var Sentaku02: UIButton!

  • 画面は下記のとおりです。最初はキーボードはでておらず画面をタップして文字記入後削除ボタンを押して文字を消したいと思っております。

イメージ説明

  • 下記の機能は成功しています

カーソルを最初に移動
カーソルを文字末尾に移動
カーソルを左に1字移動
カーソルを右に1字移動
カーソルの左の文字を削除
カーソルの右文字を削除
全文字選択

  • 関連のteratail質問項目は下記のとおりです。

全選択
カーソルの左文字を削除
カーソルの右文字を削除

  • このアプリの目的は年寄りのための音声入力補助アプリです。

音声入力は文字の修正が沢山発生しますが、年寄りは画面をタップして
選択、削除、コピーペーストなどが苦手です。指が乾いたり震えるからです。
そこでボタンの操作でそれを行おうとゆうものです。

以上よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

一つずついきます

###コード

swift

1@IBAction func selectLeftCharacter(_ sender: UIBarButtonItem) { 2 3 4 if let selectedRange = textView.selectedTextRange { 5 6 guard let currentPosition = textView.position(from: selectedRange.end, in: .left, offset: 0), 7 let leftPosition = textView.position(from: selectedRange.start, in: .left, offset: 1) 8 else { return } 9 10 textView.selectedTextRange = textView.textRange(from: currentPosition, to: leftPosition) 11 } 12 13 14 }

あとエラーが出る理由はswift4で書かれてないからですね。

投稿2017/11/16 10:49

編集2017/11/16 12:24
xAxis

総合スコア1349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Tomzy

2017/11/16 12:08

書いたコメントが掲載されないので再度書き込みます。 早速のご回答ありがとうございました。絵文字含め選択されます。これからコードの意味をよく考えて1文字だけでなく連打したときずっと連続して選択するように修正を試みます。
xAxis

2017/11/16 12:15

了解です。わからない点がありましたらいつでもどうぞ。
xAxis

2017/11/16 12:16

あとUITextView.deleteBackward()の件なんですが新しく投稿したコメント読まれました?
xAxis

2017/11/16 12:23

あー上のコード修正必要ですね。修正します。
Tomzy

2017/11/16 13:05

質問です。if文と guard文をCommentOutして下のように書いても機能します。if文と guard文は何のためにあるのでしょうか。事前に全選択をしておいても機能します。連打で有効な選択は最後の表示コードを修正すればよいと思い、いろいろやっていますがエラーがでてまだ機能していません。 // //←選択を押した時⇒左側を選択する @IBAction func sentaku02(_ sender: Any) { //if let selectedRange = InputView.selectedTextRange { let selectedRange = InputView.selectedTextRange // guard let leftPosition = InputView.position(from: selectedRange.start, in: .left, offset: 1) else { return } let leftPosition = InputView.position(from: (selectedRange?.start)!, in: .left, offset: 1) //let newPosition = InputView.beginningOfDocument InputView.selectedTextRange = InputView.textRange(from: (selectedRange?.start)!, to: leftPosition!) }
Tomzy

2017/11/16 13:13

「カーソルの左側を削除する場合もう一つ(というかこっちの方がはるかに楽な)アプローチがあります。それはUITextView.deleteBackward()を利用する方法です。こっちの方が楽に削除出来るかと。」は読みましたが、他にコメントありましたか?
Tomzy

2017/11/16 13:15

そして、それを折り込んでカーソルの左を削除するコードは組み立てました。
xAxis

2017/11/16 13:17

>if文と guard文をCommentOutして下のように書いても機能します。if文と guard文は何のためにあるのでしょうか。 これはInputView.selectedTextRangeとInputView.position(from:,in:,offset:)がOptional型の値だから、と言うことになります。 guard let leftPosition = InputView.position(from: selectedRange.start, in: .left, offset: 1) else { return } に関して言えばleftPositionの有無を調べてるだけにすぎませんが。 Optionalってなに?ってなった場合は https://qiita.com/maiki055/items/b24378a3707bd35a31a8 これとかざっくりとではありますが分かりやすいかもです。
xAxis

2017/11/16 13:19

>左側の文字の削除は >@IBAction func tap(_ sender: UIBarButtonItem) { >textView.deleteBackward() >} >これでもいいです。 このコメントです。
xAxis

2017/11/16 13:20

左の文字の削除はUITextView.deleteBackward()を織り込むのではなく単体で使った方が楽かもですね。
Tomzy

2017/11/16 13:22

はいっ、じっくり勉強してみます。ありがとうございました。 CommentOutして書いたコードを自動で大分直されました。その中に?が大分でてきました。 ところで別の質問の下記コメントがあるのを見つけました。あわせて勉強します。 2017/11/16 20:08 左側の文字の削除は @IBAction func tap(_ sender: UIBarButtonItem) { textView.deleteBackward() } これでもいいです。 more_horiz xAxis xAxis 2017/11/16 20:10 ちなみにdeleteForward()は無いので実装しました。今までやってきた事がdeleteForward()とでも言えるような内容です。まだ詰めなければなりませんが。
xAxis

2017/11/16 13:23

あーそれですね。
xAxis

2017/11/16 13:31

これリアルタイムでコミュニケーションが取れる場があれば(僕が)混乱しなくて済むような気がするんですよね。今回の一連の回答しててどうしても前の回答と連動することが多いから自分自身なにやってるのかよくわからなくなってしまってますw
xAxis

2017/11/16 13:31

あっでももしまた疑問がありましたらご遠慮なくどうぞ。回答がちょっと混乱してる可能性がありますがw
Tomzy

2017/11/19 05:59

下記のとおりコードを組んだのですがエラーがでて前に進みません。助言をお願いします。 エラーは最後の行に Cannot assign value of type 'UITextRange?' to type 'NSRange' (aka '_NSRange')  とでます。 コード  ↓ ↓ ↓ //←選択を押した時⇒左側を選択する @IBAction func sentaku02(_ sender: Any) { if let selectedRange = InputView.selectedTextRange { guard let currentPosition = InputView.position(from: selectedRange.end, in: .left, offset: 0), let leftPosition = InputView.position(from: selectedRange.start, in: .left, offset: 1) else{ return } InputView.selectedRange = InputView.textRange(from: currentPosition, to: leftPosition) }}
xAxis

2017/11/19 06:35 編集

助言と致しましては InputView.selectedRange = InputView.textRange(from: currentPosition, to: leftPosition) warning出てる行ってここですかね。 warningの意味としては「NSRangeの型のとこにUITextRangeの型の値は代入(割り当て)出来ないよ!」くらいの意味です。 ちなみにInputView.textRange(from:,to:)の型はUITextRangeです。そしてこのコードの中にUITextRange型の値がもう一つあります。現状あるInputView.selectedRangeの型は上記の通りNSRangeです。 こんな感じで考えてみてください。 P.S.これでわからなかった場合orわかった場合どちらでももう一つ追加でコメントがあります。今回のwarningが出た原因に関するコメントです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問