0

I have HTML string that I am displaying inside UITextView as NSAttributedString. Now I want to insert/replace a string inside the attributed string with respect to some conditions.

  • Attributed string itself have multiple sections and I need to insert a string in a specific section.
  • The main thing is to identify section as it might be anywhere in the string.
  • Need To identify section as relative to its near neighboring sections.

I have done the rest of the work in which I can replace part of the string in NSAttributedString with my custom new string. I just need string section identification ideas.

Here is the screenshot of the Attributed Text

enter image description here

Now you can see there are three sections Joint (R), Metatarsophalangeal (R) and Joint (L). They are always random instead of at specific location.

The data in them is in ordered but it may have more subsections.

Now If I want to all of the string inside Metatarsophalangeal section how can I get it?

5
  • Are these headings have the same text as always? Are they Bold only? Commented Mar 6, 2017 at 7:22
  • Yes the Headings have same text Commented Mar 6, 2017 at 7:36
  • you want to change strings inside Flexion : Angle: 0-5, Quality : Crepitus or Angle, Quality values Commented Mar 6, 2017 at 7:39
  • I need to find rangeOfString of the main section rest is already achieved. Just need to know start and end of each section, considering it might appear randomly in the list. Commented Mar 6, 2017 at 7:49
  • please send html text in your question Commented Mar 6, 2017 at 11:54

2 Answers 2

1

It's possible to set arbitrary attributes in your string. For example [string setAttributes:@{ @"my custom attribute name" : @(YES), ...} range:range];

Then, when you want to use those attributes again, you can use enumerateAttribute:. Note the use of options:NSAttributedStringEnumerationReverse to avoid overwriting data in copyOfString.

[string enumerateAttribute:@"my custom attribute name" inRange:NSMakeRange(0, string.length) options:NSAttributedStringEnumerationReverse usingBlock:^(id  _Nullable value, NSRange range, BOOL * _Nonnull stop) {
    if (value){ // Do something here
        [copyOfString replaceCharactersInRange:range withString:@"______"];
    }
}];
Sign up to request clarification or add additional context in comments.

2 Comments

If i would have known the range i couldnt have any problem at first place. I need to identify sections range not setting attributes on them.
Your question seems to focus on NSAttributedString. There are many methods of constructing one, which may or may not use NSRange. If you're not constructing the string yourself and just instantiating it from HTML you will just have to find the start/end ranges of those headers using rangeOfString:
0

I think it could be the solution for your case, I used strong HTML attribute as something unique which cover each section and then check the matched string(section) and append the desirable text to each section (had I known your html string I could write more exact code for that):

// sample HTML String
NSString *htmlString = @"<strong>Section (A)</strong><br>...<br><strong>Section (B)</strong><br>...<br><strong>Section (C)</strong><br>...<br>";

NSString *regexString = @"<strong>(.*?)</strong>"; // or whatever makes sense for your scenario
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:regexString
                                          options:NSRegularExpressionCaseInsensitive
                                            error:nil];

NSMutableString* mutableString = [htmlString mutableCopy];
NSInteger offset = 0; // keeps track of range changes in the string
// due to replacements.
for (NSTextCheckingResult* result in [regex matchesInString:htmlString
                                                    options:0
                                                      range:NSMakeRange(0, [htmlString length])]) {

    NSRange resultRange = [result range];
    resultRange.location += offset; // resultRange.location is updated
    // based on the offset updated below

    // implement your own replace functionality using
    // replacementStringForResult:inString:offset:template:
    // note that in the template $0 is replaced by the match
    NSString* match = [regex replacementStringForResult:result
                                               inString:mutableString
                                                 offset:offset
                                               template:@"$0"];
    NSLog(@"match %@", match);

    NSString* append;
    if ([match containsString:@"Section (A)"]) {
        append = @"AppendForSectionA";
    } else if ([match containsString:@"Section (B)"]) {
        append = @"AppendForSectionB";
    } else if ([match containsString:@"Section (C)"]) {
        append = @"AppendForSectionC";
    } else {
        append = @"";
    }

    NSString* replacement = [match stringByAppendingString:append];

    // make the replacement
    [mutableString replaceCharactersInRange:resultRange withString:replacement];

    // update the offset based on the replacement
    offset += ([replacement length] - resultRange.length);
}

NSLog(@"resulting string: %@", mutableString);

And the result would be:

<strong>Section (A)</strong>AppendForSectionA<br>...<br><strong>Section (B)</strong>AppendForSectionB<br>...<br><strong>Section (C)</strong>AppendForSectionC<br>...<br>

Screen-shot before change: enter image description here

Screen-shot after change: enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.