Closed mbenz89 closed 1 year ago
I implemented the functionality like this, so that not every input will lead to executing getOrCreateColor for a not yet completed hashtag.
I think you may have forgotten to post some sample code? Could you add code demonstrating what you're talking about?
If I understand this issue correctly, you're saying you would like getOrCreateColor()
to run only when the user types a completed hashtag?
Edit: Are you using the AppKit or UIKit version of the editor?
@kyle-n Thanks for your reply and sorry for the long delay!
If I understand this issue correctly, you're saying you would like getOrCreateColor() to run only when the user types a completed hashtag?
Exactly.
Edit: Are you using the AppKit or UIKit version of the editor?
The UiKit Version.
Here is my code:
/** matches text starting with #
**/
let regexHashtagWriting = try! NSRegularExpression(pattern: "#[\\u00C0-\\u017Fa-zA-Z0-9_]+", options: [])
let regexHashtagFinished = try! NSRegularExpression(pattern: "#[\\u00C0-\\u017Fa-zA-Z0-9_]+(?=[^\\u00C0-\\u017Fa-zA-Z0-9_])", options: [])
private func createRules() -> [HighlightRule] {
// this is invoked after each keyinput. for all words! we do not want to query the db for all tags and all inputs. so we first render a tag blue and only after the space was inserted, the actual color will be added
[HighlightRule(pattern: regexHashtagWriting, formattingRules: [
TextFormattingRule(fontTraits: [.traitBold]),
TextFormattingRule(key: .foregroundColor) { content, range in
UIColor.systemBlue
},
]), HighlightRule(pattern: regexHashtagFinished, formattingRules: [
TextFormattingRule(fontTraits: [.traitBold]),
TextFormattingRule(key: .foregroundColor) { content, range in
do {
// THIS IS ALWAYS EXECUTED
let tag = try notePaneAdapter.getOrCreateTag(tag: content)
return UIColor(hex: tag.color) ?? UIColor.blue
} catch let error {
print(error)
return UIColor.blue
}
},
])]
}
regexHashtagFinished
matches a hashtag followed by a non-hashtag symbol (i.e. no letter or digit). Coloring works as expected: While writing, the hashtag will be blue, after adding a space char, it will get a random color assigned.
For some reason, the callback that computes the random color will be executed every time, but the returned color will not be applied to the text.
Hope that helped :)
sorry for the long delay!
No worries, because now I have left you with an embarrassingly long delay. Apologies.
If you look at the source code, specifically HighlightingTextEditor.swift, you can see on line 134 we run calculateValue()
, the callback you provide when instantiating a TextFormattingRule
, every time formatting is applied. Formatting is applied whenever the text changes. The reason is because you may want to format the content differently, depending on on the content of the text editor.
It is intended behavior to run the callback every time formatting is applied, so no updates to the library are needed here.
In your case, it sounds like it would be easier to compute a random color once, outside the HLTE code, and create a TextFormattingRule
like this:
let myRandomColor = UIColor.blue
// ...
TextFormattingRule(key: .foregroundColor, value: myRandomColor)
Does that help?
HI! First of all, thanks for providing this great library!
I basically have two regex expressions:
#fini
)#finished.
)I am using 1. to highlight a hashtag in some color during typing. When the user finished typing, the proper color should be taken for the hashtag, which is loaded from a database. I use 2. to detect that the user has finished typing.
I implemented the functionality like this, so that not every input will lead to executing
getOrCreateColor
for a not yet completed hashtag.From the user's perspective, this works perfectly fine. The not-yet complete hashtag will be blue until the user types a whitespace character (for example). However, I can notice from my logs that the callback for the non-matching regex (2) is still executed on each input to the editor. It seems that the result is just not used if there is no match, even though it is computed (I am guessing here).
I am super new to Swift which is why I lack better solutions currently. Do you have any ideas how I could implement the requested behavior with your editor component? Any way to circumvent the execution of the
TextFormattingRule
callback when the enclosingHighlightRule
'spattern
doesn't match?I thought about using
onCommit
, as this is executed when the typing is done. However, I have no idea how I could trigger a highlight change or change the highlighting manually in theonCommit
callback.Thanks in advance!