Swift: Checkbox insertion in UITextView of a UITableViewCell and using UITapGestureRecognizer to recognize taps on the checkbox

﹥>﹥吖頭↗ 提交于 2019-12-06 02:26:42

It is not possible to add a UIButton or other UIControl in the middle of the text of a UITextView. What you could do though, is using the attributedString property of the UITextView to render a checkbox character. You can do this by using a custom font with a character that matches the checkbox (checked and unchecked). You will need to add a UITapGestureRecognizer to the UITextView and then convert the point of the touch to detect if a checkbox was tapped and change the checkbox character from a selected checkbox to unselected and vice versa. You also need to bear in mind that you will have to set a delegate on the UITapGestureRecognizer to make sure it allows simultaneous touches with the normal touches for moving the cursor and only intercept the tap when it is on a checkbox symbol.

You can add a button in a toolbar above the keyboard which will add the checkbox symbol to the text (see this solution: How can I add a toolbar above the keyboard?).

I hope this helps.

Answer to your further questions

  • My UITapGestureRecognizer doesn't work as intended, it doesn't seem to respond to the taps.

    This is because you try to use a single gesture recognizer on all of your textviews. You should create a new UITapGestureRecognizer for each UITextView. Now it will be removed from the previous views as you are adding the to the later views (so it will only detect the tap on the last cell that is dequeued).

  • How can I check if my checkbox is tapped on and replace the characters with the checkmark?

    The code you have inside checkboxTapDone(sender:) should deal with that. You are mostly there, but the range you are creating should only be 1 character, not 9. You then need to compare the substring value with the value of a checked and unchecked character. Then update the eventText.attributedText with the opposite character.

  • How do I insert the checkbox only at the beginning of the line which the user's cursor is on?

    The following code snippet should help you determine the range where you can insert the checkbox character.

var beginningOfLineForSelection = textView.selectedTextRange.flatMap {    
    textView.selectionRects(for: $0).first as? UITextSelectionRect 
}?.rect.origin ?? .zero
beginningOfLineForSelection.x = 0

let layoutManager = textView.layoutManager
let firstGlyphOnLine = layoutManager.glyphIndex(
    for: beginningOfLineForSelection,
    in: textView.textContainer,
    fractionOfDistanceThroughGlyph: nil
)

let insertCheckboxRange = NSMakeRange(firstGlyphOnLine, 0)

Answer to smaller new issues

  • The reason you weren't seeing the replaceCharacters(in:with:) method (which takes an NSRange as its first argument), is because you were using the NSAttributedString (which isn't mutable). You need to first create a mutable copy of the attributedText property. Then you can change the text and set it again on the UITextView. See code snippet below for an example.
let newText = NSMutableAttributedString(attributedString: textView.attributedText)
newText.replaceCharacters(in: rangeOfCharactersToReplace, with: newCharacters)
textView.attributedText = newText 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!