• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Trouble overriding text editing methods
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Trouble overriding text editing methods


  • Subject: Trouble overriding text editing methods
  • From: Gideon King <email@hidden>
  • Date: Mon, 19 Apr 2004 18:04:33 +1000

I'm having a couple of problems with overriding the default text behavior in a text view. The problem is that I need to adjust both the range that the change is happening over, and the text that is put in its place under certain circumstances. I found that just overriding it at the text storage level didn't work because if the text storage changed a different range than that "approved" by the text view (by shouldChangeTextInRange...), the undo system would get all out of sync.

What I am doing is that I am overriding the following items in my textview subclass:
insertText:
setString:
deleteBackward:
deleteForward:

These methods essentially do the following sort of behavior (this example taken from insertText: and modified to show the behind the scenes stuff that I actually do in the text storage)

NSRange selRange = [self selectedRange];
NSDictionary *attrs;

if (selRange.location == NSNotFound ||
(selRange.length == 0 && selRange.location == [[self textStorage] length])) {
// We need to use the typing attributes
attrs = [self typingAttributes];
} else {
attrs = [[self textStorage] attributesAtIndex:selRange.location effectiveRange:NULL];
}

replacementRange = // Calculate the actual range for the text replace
replacementString = // Work out what the actual replacement string has to be

// We know that this will be approved, so don't need to take notice of the result, but
// it appears to have to be done so that undo works properly
[self shouldChangeTextInRange:replacementRange replacementString:replacementString];
[[self textStorage] beginEditing];
[[self textStorage] replaceCharactersInRange:replacementRange withString:replacementString];
(which calls edited:NSTextStorageEditedCharacters range:replacementRange changeInLength:[contents length] - origLen];
[[self textStorage] endEditing];
[tv didChangeText];

NSRange newRange = NSMakeRange(replacementRange, [replacementString length]);

if (!attrs) {
attrs = // some standard formatting attributes
}
[self shouldChangeTextInRange:newRange replacementString:nil];
[[self textStorage] beginEditing];
[[self textStorage] setAttributes:attrs range:newRange];
[[self textStorage] endEditing];
[self didChangeText];
[self setTypingAttributes:attrs];
[self scrollRangeToVisible:[self selectedRange]];

Now this approach seems to work in most cases and most respects, but there are a few problems I have come across:
1. When I undo the changes, they are not globbed together as they normally would be for text edits - each character change is undone individually. Does anyone know what triggers the text system to begin a new undo group? I know it is triggered when a non-text undo operation is entered on to the undo stack, but that would not seem to be the case in this instance.
2. When I do a deleteForward, and my behind the scenes stuff extends the range and replacement characters, the internals of the text editing system seem to go into an endless loop in [NSMutableAttributedString(NSMutableAttributedStringKitAdditions) fixFontAttributeInRange:]. This occurs when the new selection crosses a paragraph boundary.
3. This is used in a multi-page document (using the TextEdit model), and when it wraps on to another page, it throws an exception *** NSRunStorage, _NSBlockNumberForIndex(): index (361) beyond array bounds (0), which I presume is because the affected textview is now the new one - does this mean that I need to use textViewForBeginningOfSelection to do the end editing even if I did the begin editing on the previous text view?
4. Occasionally I get an out of range type error (but that may be somewhere else in my code that is triggering that one)

All this means that what I thought would be a fairly straightforward way of accomplishing what I needed to do has turned out to be more difficult and error prone than I had thought.

Can anyone help with any of the above items, or suggest a different approach which would be better? This is one of the few remaining bugs I need to fix before a new release, so any help would be appreciated.


Thanks

Gideon.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.


  • Prev by Date: Re: NSString's intValue method
  • Next by Date: Re: Demarkation seen on NSScrollView,Why is it?
  • Previous by thread: Re: Demarkation seen on NSScrollView,Why is it?
  • Next by thread: How to make mouseDown repond for both the matrix and Scrollview?
  • Index(es):
    • Date
    • Thread