Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First, construct the attributed string and save the range of the interactive text and the text itself.</p> <p>Then, draw the attributed string with CoreText Framework, keep the CTFrameRef.</p> <pre><code>CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString); CGMutablePathRef path = CGPathCreateMutable(); CGPathAddRect(path, NULL, bounds); CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL); CFRelease(framesetter); CTFrameDraw(frame, context); //CFRelease(frame); CGPathRelease(path); </code></pre> <p>The last, override the [view touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event] like this:</p> <pre><code>- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSSet *allTouches = [event allTouches]; if ([allTouches count] == 1) { UITouch *touch = (UITouch *)[allTouches anyObject]; CGPoint touchPoint = [touch locationInView:self]; // Convert to coordinate system of current view touchPoint.y -= self.bounds.size.height; touchPoint.y *= -1; CGPathRef statusPath = CTFrameGetPath(statusCTFrame); NSString *touchedInterStr = nil; if (CGPathContainsPoint(statusPath, NULL, touchPoint, FALSE)) { touchedInterStr = [self getInteractiveStringInFrame:statusCTFrame atPosition:touchPoint]; } else { return ; } } } - (NSString *)getInteractiveStringInFrame:(CTFrameRef)frame atPosition:(CGPoint)point { CGPathRef path = CTFrameGetPath(frame); CGRect rect; CGPathIsRect(path, &amp;rect); // Convert point into rect of current frame, to accurately perform hit testing on CTLine CGPoint pointInsideRect = point; pointInsideRect.x = point.x - rect.origin.x; CFArrayRef lines = CTFrameGetLines(statusCTFrame); CFIndex count = CFArrayGetCount(lines); CGFloat curUpBound = rect.origin.y + rect.size.height; CFIndex touchedIndex = -1; for (CFIndex pos = 0; pos &lt; count; pos++) { CTLineRef curLine = CFArrayGetValueAtIndex(lines, pos); CGFloat ascent, descent, leading; CTLineGetTypographicBounds(curLine, &amp;ascent, &amp;descent, &amp;leading); CGFloat curHeight = ascent + descent + leading; if (pointInsideRect.y &gt;= curUpBound-curHeight &amp;&amp; pointInsideRect.y &lt;= curUpBound){ touchedIndex = CTLineGetStringIndexForPosition(curLine, pointInsideRect); // Hit testing break; } curUpBound -= curHeight; } if (touchedIndex == -1) return nil; NSEnumerator *enumerator = [interactiveStrs objectEnumerator]; InteractiveString *curString; while ((curString = (InteractiveString *)[enumerator nextObject])) { if (NSLocationInRange(touchedIndex, curString.range)) { return curString.content; } } return nil; } </code></pre> <p>You get the interactive text in touchesEnded, then you could do anything you want, like trigger a delegate method.</p> <p>PS: this is the old-fashion solution, I heard that iOS5 had provided something like an enhanced UIWebView to implement the requirements, maybe you could check the apple sdk document library.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload