4

iOS 6 已更新为使用 UITextView 进行富文本编辑(UITextView 现在获得了属性文本属性——这是愚蠢的不可变的——)。这是在 NDA 下在 iOS 6 Apple 论坛上提出的一个问题,由于 iOS 6 现已公开,因此可以公开...

在 UITextView 中,我可以撤消任何字体更改,但不能撤消视图属性字符串副本中的替换。使用此代码时...

- (void) replace: (NSAttributedString*) old with: (NSAttributedString*) new

{
1.    [[myView.undoManager prepareWithInvocationTarget:self] replace:new with:old];
2.    old=new;

}

...撤消效果很好。

但是,如果我添加一行以使结果在我的视图中可见,则 undoManager 不会触发“replace:with:”方法,因为它应该......

- (void) replace: (NSAttributedString*) old with: (NSAttributedString*) new

{
1.    [[myView.undoManager prepareWithInvocationTarget:self] replace:new with:old];
2.    old=new;
3.    myView.attributedText=[[NSAttributedString alloc] initWithAttributedString:old];

}

任何想法?对于我尝试在“2”行使用的 MutableAttributedString 的任何替换方法,无论是否使用范围,我都有同样的问题......

4

3 回答 3

2

嗯,哇,我真的没想到这会奏效!我找不到解决方案,所以我开始尝试任何事情......

- (void)applyAttributesToSelection:(NSDictionary*)attributes {
    UITextView *textView = self.contentCell.textView;

    NSRange selectedRange = textView.selectedRange;
    UITextRange *selectedTextRange = textView.selectedTextRange;
    NSAttributedString *selectedText = [textView.textStorage attributedSubstringFromRange:selectedRange];

    [textView.undoManager beginUndoGrouping];
    [textView replaceRange:selectedTextRange withText:selectedText.string];
    [textView.textStorage addAttributes:attributes range:selectedRange];
    [textView.undoManager endUndoGrouping];

    [textView setTypingAttributes:attributes];
}
于 2014-06-17T13:10:27.997 回答
1

Mac 催化剂 (iOS14)

UITextView可以undoManager免费管理撤消和重做,无需任何额外代码。

但是替换它attributedText会重置undoManager(更新文本及其属性textStorage对我也不起作用)。我发现在格式化文本而不替换attributedText但通过标准编辑操作(右键单击突出显示文本>字体>粗体(Mac Catalyst))时,撤消和重做将正常工作。

所以要解决这个问题:

  1. 您需要将allowsEditingTextAttributesof设置UITextViewtrue,这将使 UITextView 支持 undo 和 redo attributedText
self.textView.allowsEditingTextAttributes = true
  1. 如果您想更改符合的、attributedTextreplace(_:withText:)、或UITextInputinsertText(_:)文本。deleteBackward()UIKeyInputUITextView
self.textView.replace(self.textView.selectedTextRange!, withText: "test")
  1. 如果要更改文本的属性,请改用updateTextAttributes(conversionHandler:)of UITextView
self.textView.updateTextAttributes { _ in
                
    let font = UIFont.boldSystemFont(ofSize: 17)
    let attributes: [NSAttributedString.Key: Any] = [
        .font: font,
    ]
    
    return attributes
}

要更改特定范围内的文本及其属性,请修改selectedRange.UITextView

要实现撤消和重做按钮,请查看以下答案:https ://stackoverflow.com/a/50530040/8637708

我已经用 Mac Catalyst 进行了测试,它应该也可以在 iOS 和 iPadOS 上运行。

于 2021-09-06T11:58:40.333 回答
0

撤消管理器在设置其“文本”或“属性文本”属性后被重置,这就是它不起作用的原因。我不知道这种行为是错误还是设计使然。

但是,您可以改用 UITextInput 协议方法。

  • (void)replaceRange:(UITextRange *)range withText:(NSString *)text

这行得通。

于 2013-02-17T12:56:17.110 回答