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

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

ただいまの
回答率

90.76%

  • Swift

    6696questions

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

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

解決済

回答 1

投稿

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

Tomzy

score 71

やりたいこと

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質問項目は下記のとおりです。
    全選択
    カーソルの左文字を削除
    カーソルの右文字を削除

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

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

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

一つずついきます

コード

@IBAction func selectLeftCharacter(_ sender: UIBarButtonItem) {


        if let selectedRange = textView.selectedTextRange {

            guard let currentPosition = textView.position(from: selectedRange.end, in: .left, offset: 0),
            let leftPosition = textView.position(from: selectedRange.start, in: .left, offset: 1)
            else { return }

            textView.selectedTextRange = textView.textRange(from: currentPosition, to: leftPosition)
        }


    }

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

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/16 21:08

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

    キャンセル

  • 2017/11/16 21:15

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

    キャンセル

  • 2017/11/16 21:16

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

    キャンセル

  • 2017/11/16 21:23

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

    キャンセル

  • 2017/11/16 22: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!)


    }

    キャンセル

  • 2017/11/16 22:13

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

    キャンセル

  • 2017/11/16 22:15

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

    キャンセル

  • 2017/11/16 22: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

    これとかざっくりとではありますが分かりやすいかもです。

    キャンセル

  • 2017/11/16 22:19

    >左側の文字の削除は

    >@IBAction func tap(_ sender: UIBarButtonItem) {
    >textView.deleteBackward()
    >}

    >これでもいいです。

    このコメントです。

    キャンセル

  • 2017/11/16 22:20

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

    キャンセル

  • 2017/11/16 22: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()とでも言えるような内容です。まだ詰めなければなりませんが。

    キャンセル

  • 2017/11/16 22:23

    あーそれですね。

    キャンセル

  • 2017/11/16 22:31

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

    キャンセル

  • 2017/11/16 22:31

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

    キャンセル

  • 2017/11/19 14: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)
    }}

    キャンセル

  • 2017/11/19 15:34 編集

    助言と致しましては

    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が出た原因に関するコメントです。

    キャンセル

  • 2017/12/22 15:21

    xAxisさんへ
    こんにちは。お世話になったアプリがリリースされました。ご報告します。
    「音声入力アシスト」 https://itunes.apple.com/jp/app/id1324919578?mt=8

    キャンセル

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

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

関連した質問

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

  • Swift

    6696questions

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