【问题标题】:How do I add an unordered list or a bullet point every new line in a UITextView如何在 UITextView 中的每一行添加无序列表或项目符号
【发布时间】:2014-12-04 21:41:11
【问题描述】:

所以基本上我想向UITextView 添加一个无序列表。而另一个UITextView 我想添加一个有序列表。

我尝试使用此代码,但它只在用户第一次按 Enter 后给了我一个要点(仅此而已),我什至无法退格。

- (void)textViewDidChange:(UITextView *)textView
{
    if ([myTextField.text isEqualToString:@"\n"]) {
        NSString *bullet = @"\u2022";
        myTextField.text = [myTextField.text stringByAppendingString:bullet];
    }
}

如果您只找到一种使用 Swift 执行它的方法,请随时发布 Swift 版本的代码。

【问题讨论】:

标签: ios objective-c xcode swift


【解决方案1】:

问题是你正在使用

if ([myTextField.text isEqualToString:@"\n"]) {

作为您的条件,如果您的myTextField.text 的整体等于“\n”,则该块将执行。但是,如果您没有输入任何内容“\n”,则整个myTextField.text 仅等于“\n”。这就是为什么现在,此代码仅在“用户第一次按下回车时”起作用;当你说“我什至不能退格”时,问题实际上是通过调用textViewDidChange:重新添加项目符号点,因为仍然满足相同的条件。

在这种情况下,我建议不要使用textViewDidChange:,而是使用shouldChangeTextInRange:,这样无论替换文本在UITextView 文本字符串中的位置如何,您都可以知道它是什么。通过使用这种方法,即使在文本块的中间输入换行符,您也可以自动插入项目符号点......例如,如果用户决定输入一堆信息,然后跳回几行输入更多信息,然后尝试在两者之间按换行符,以下应该仍然有效。以下是我的建议:

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    // If the replacement text is "\n" and the
    // text view is the one you want bullet points
    // for
    if ([text isEqualToString:@"\n"]) {

        // If the replacement text is being added to the end of the
        // text view, i.e. the new index is the length of the old
        // text view's text...
        if (range.location == textView.text.length) {
            // Simply add the newline and bullet point to the end
            NSString *updatedText = [textView.text stringByAppendingString:@"\n\u2022 "];
            [textView setText:updatedText];
        }

        // Else if the replacement text is being added in the middle of
        // the text view's text...
        else {

            // Get the replacement range of the UITextView
            UITextPosition *beginning = textView.beginningOfDocument;
            UITextPosition *start = [textView positionFromPosition:beginning offset:range.location];
            UITextPosition *end = [textView positionFromPosition:start offset:range.length];
            UITextRange *textRange = [textView textRangeFromPosition:start toPosition:end];

            // Insert that newline character *and* a bullet point
            // at the point at which the user inputted just the
            // newline character
            [textView replaceRange:textRange withText:@"\n\u2022 "];

            // Update the cursor position accordingly
            NSRange cursor = NSMakeRange(range.location + @"\n\u2022 ".length, 0);
            textView.selectedRange = cursor;

        }
        // Then return "NO, don't change the characters in range" since
        // you've just done the work already
        return NO;
    }

    // Else return yes
    return YES;
}

【讨论】:

  • (仍在对我的答案进行一些更新,以解决中间文本视图条目。)
  • 我只有一个问题:在 if 语句中放置“文本”而不​​是 myText.text 有什么意义。我尝试放置 myText.text,但它没有用,它只适用于“文本”。所以我的问题是,有什么区别?
  • @Mike 不,问题...但是,当我在您发布的同一时间输入时,我想进行一些更新以处理中间文本视图条目与文本视图结尾条目。这不是什么大问题或区别,只是会让答案更正确......
  • @Mike 哈哈,我们有在同一时间发帖的诀窍,对吧? ;) myText.text 是文本字段中的文本,而 text 只是 replacementText,即在这种情况下为“\n”,如委托方法参数所示。
  • 我没有得到中间和结束 textview 之间的差异
【解决方案2】:

以防万一,有人正在寻找解决同一问题的 Swift 2.x 解决方案,这里有一个解决方案:

func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
    // If the replacement text is "\n" and the
    // text view is the one you want bullet points
    // for
    if (text == "\n") {
        // If the replacement text is being added to the end of the
        // text view, i.e. the new index is the length of the old
        // text view's text...


        if range.location == textView.text.characters.count {
            // Simply add the newline and bullet point to the end
            var updatedText: String = textView.text!.stringByAppendingString("\n \u{2022} ")
            textView.text = updatedText
        }
        else {

            // Get the replacement range of the UITextView
            var beginning: UITextPosition = textView.beginningOfDocument
            var start: UITextPosition = textView.positionFromPosition(beginning, offset: range.location)!
            var end: UITextPosition = textView.positionFromPosition(start, offset: range.length)!
            var textRange: UITextRange = textView.textRangeFromPosition(start, toPosition: end)!
            // Insert that newline character *and* a bullet point
            // at the point at which the user inputted just the
            // newline character
            textView.replaceRange(textRange, withText: "\n \u{2022} ")
            // Update the cursor position accordingly
            var cursor: NSRange = NSMakeRange(range.location + "\n \u{2022} ".length, 0)
            textView.selectedRange = cursor
        }

        return false


    }
    // Else return yes
    return true
}

【讨论】:

  • 这非常有效。必须对 Swift 4 语法做一些小的改动。 positionFromPosition 已重命名为 position(from: to:) 并且 textRangeFromPosition 已重命名为 textRange(from: to:)
【解决方案3】:

Swift 5.x 版本。

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        //
        // If the replacement text is "\n" and the
        // text view is the one you want bullet points
        // for
        if (text == "\n") {
            // If the replacement text is being added to the end of the
            // text view, i.e. the new index is the length of the old
            // text view's text...


            if range.location == textView.text.count {
                // Simply add the newline and bullet point to the end
                let updatedText: String = textView.text! + "\n \u{2022} "
                textView.text = updatedText
            }
            else {

                // Get the replacement range of the UITextView
                let beginning: UITextPosition = textView.beginningOfDocument
                
                let start: UITextPosition = textView.position(from: beginning, offset: range.location)!
                let end: UITextPosition = textView.position(from: start, offset: range.length)!
                
                let textRange: UITextRange = textView.textRange(from: start, to: end)!
                // Insert that newline character *and* a bullet point
                // at the point at which the user inputted just the
                // newline character
                textView.replace(textRange, withText: "\n \u{2022} ")
                // Update the cursor position accordingly
                let cursor: NSRange = NSMakeRange(range.location + "\n \u{2022} ".count, 0)
                textView.selectedRange = cursor
            }

            return false


        }
        // Else return yes
        return true
    }

【讨论】:

  • 如何在SwiftUI中将其应用到TextEditor
猜你喜欢
  • 1970-01-01
  • 2011-12-02
  • 1970-01-01
  • 2021-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多