iOS

Swift4:UITextViewの制御(修正版)

UITextViewをハンドリングする方法についての忘備録です。

要点は次の2点です。

placeholderのハンドリングと変更内容のsaveタイミング

  1. キャレットをUITextViewの外側に出さないとplaceholderの設定が自動的に行われません。外に出さないと、設定したplaceholderが文字列と認識される問題が発生します。解決方法のひとつとして、たとえばUITextFieldに文字列を置き、selectAllで選択すれば、この問題を解消できます。これには、副作用があり、selectAllのあとにキャレットを最初の文字列の前に持っていっても、pasteのポップアップが表示されてしまう問題が起きます。
  2. ない知恵を出し切っていろいろ考えたのですが、結局、次のようにしました。①UITextViewにキャレットがある間はplaceholderを表示しない仕様とする。
    ②キャレットをユーザーがUITextViewの外側に移動した場合、直前のUITextViewの変更内容をsaveし、次からplaceholderが表示される仕様とする。
    ③表のクリックやボタンのクリックなどのアクティビティが起きた場合、直前のUITextViewの変更内容をsaveする。

上記paste popup画面については、pasteできる状態にあるから表示されると推測しています。よって、copy and pasteの機能追加をしてこのpasteを取り消せばいいのではないか、と考えています。以前、macOSでは、copy and pasteを実装したことがあります。その経験からするとそんなにむずかしい話ではありません。少し余裕ができたら検討したいと思います。

 

@IBAction func ExecIBAGo2Click(){//<*Process when a row in UITableView is kicked*>
        self.ExecClickedRow(self.Z.qRow, pCount:0)                 // 🔵🔵Click Process🔵🔵
   }//=============================================================//
    func ExecClickedRow(_ pRow:Int, pCount:Int) {                  //<*pCount>=0: Click Process pCount<0: Update process after a row removal*>
        if pRow < 0 || pRow >= Z.rcArray.count || Z.rcArray.count <= 0 {//Available?
            Z.qRow          = -999                                  //Out of the Array.
            return                                                  //♻️return♻️ Go back.
        } else { }                                                  //
        if pCount >= 0 {                                            //1st click or 2nd click and later?
            ExecSetValues2Array(Z.qRow)                             //Save the previous values in tow UITextField and one UITextView.
        } else { }                                                  //
        Z.qRow              = pRow                                  //Set the target row.
        Z.maybeLastRow      = pRow                                  //Set the target row just in case.
        ExecSetDateTitleMemo(Z.qRow)                                //Draw ⏰Date & Time 📅Group 📚Title.
        Z.sortURL           = Z.rcArray[Z.qRow][Z.fURL] as! String  //Set the current URL in case of clicking the screen shot.
        Z.yTableView.selectRow(at: IndexPath(row: Z.qRow, section: 0), animated: true, scrollPosition: .top)//Select the current row.
       Z.yTableView.reloadData()                                    //🍋🍋reloadData🍋🍋
    }//=============================================================//
    func ExecSetDateTitleMemo(_ pRow:Int) {                         //<*Set values to UITextView*>
        Z.yUserNote.text    = “”                                    //
        if pRow < 0 || pRow >= Z.rcArray.count { return }           //♻️return♻️ The previous row is out of the array.
        else { }                                                    //
        Z.yGroup.text       = (Z.rcArray[pRow][Z.fGroup] as! String)//Set Group value.
        Z.yTitle.text       = (Z.rcArray[pRow][Z.fTitle] as! String)//Set Title value.
        let wImage:UIImage  = Com.CallResizeCapturedImage((Z.rcArray[pRow][Z.fScreen] as! UIImage), pImageView: Z.yScreen)//Set Screenshot.
        Z.yScreen.image     = wImage                                //
        let wCheck:NSMutableAttributedString?   = (Z.rcArray[pRow][Z.fNote] as? NSMutableAttributedString) //Check UserNote.
        if wCheck == nil || (wCheck?.string.count)! <= 0  {         //Set the placeholder if the caret is out of the UITextView and no data.
            if wkEdited == “” { Z.yUserNote.attributedText = wkPlaceholder }//
            else              {  }                                  //
        } else { Z.yUserNote.attributedText = Z.rcArray[pRow][Z.fNote] as! NSMutableAttributedString }//Set UserNote.
    }//=============================================================//
    func textViewDidBeginEditing(_ textView: UITextView) {          //<*Watch the UITextView(Note Area)*>
        if Z.yUserNote.text == wkPlaceholder.string {               //Placeholder string?
            Z.yUserNote.text            = “”                        //No data.
            Z.yUserNote.textColor       = UIColor.black             //Black. (Placeholder: Gray)
            wkEdited                    = “🍎”                      //🍎Begin Editing with no data.
        } else {                                                    //
            wkEdited                    = “🍎”                      //🍎Begin Editing with data.
        }                                                           //
    }//=============================================================//
    func textViewDidEndEditing(_ textView: UITextView) {            //<*Watch the carsor (caret)*>
        if Z.yUserNote.text.count <= 0 || Z.yUserNote.text == wkPlaceholder.string {//No data or placeholder?
            wkEdited                    = “”                        //Clear the Edit sign.
        }else if wkEdited == “🍎” {                                 //Going on editing the UITextView?
            wkEdited                    = “⛔️”                      //⛔️End.
        } else { }                                                  //
    }//=============================================================//

Screenshot 2018-06-10 13.32.22

Categories: iOS, Swift, 技術