I'm trying to do a quite simple thing: write an URL inside a PDF file that can be actually clicked by the user.
I know for sure that using libharu it can be done. What I'm looking for is to do the same using Core Graphics since the whole code I already have in my app is already using those methods.
== edit ==
I think I found something: UIGraphicsSetPDFContextURLForRect
but I can't make it to work.
I'm using something like:
NSURL *url = [NSURL URLWithString:@"http://www.google.com"];
UIGraphicsSetPDFContextURLForRect( url, CGRectMake(0, 0, 100, 100));
The rect is not clickable, though.
Ok I managed to figure out why it wasn't working.
Core Graphics context are "reversed" in the sense of having the origin at the bottom left of the page while UIKit has the origin in the top-left corner.
This is the method I came up with:
- (void) drawTextLink:(NSString *) text inFrame:(CGRect) frameRect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform ctm = CGContextGetCTM(context);
// Translate the origin to the bottom left.
// Notice that 842 is the size of the PDF page.
CGAffineTransformTranslate(ctm, 0.0, 842);
// Flip the handedness of the coordinate system back to right handed.
CGAffineTransformScale(ctm, 1.0, -1.0);
// Convert the update rectangle to the new coordiante system.
CGRect xformRect = CGRectApplyAffineTransform(frameRect, ctm);
NSURL *url = [NSURL URLWithString:text];
UIGraphicsSetPDFContextURLForRect( url, xformRect );
CGContextSaveGState(context);
NSDictionary *attributesDict;
NSMutableAttributedString *attString;
NSNumber *underline = [NSNumber numberWithInt:NSUnderlineStyleSingle];
attributesDict = @{NSUnderlineStyleAttributeName : underline, NSForegroundColorAttributeName : [UIColor blueColor]};
attString = [[NSMutableAttributedString alloc] initWithString:url.absoluteString attributes:attributesDict];
[attString drawInRect:frameRect];
CGContextRestoreGState(context);
}
What this method does is:
UIGraphicsSetPDFContextURLForRect
will mark it as clickablexformRect
) as clickable using the aforementioned methodHere is converted code for Swift 5
let context = UIGraphicsGetCurrentContext()
let ctm = context?.ctm
// Translate the origin to the bottom left.
// Notice that 842 is the size of the PDF page.
ctm?.translatedBy(x: 0.0, y: 842)
// Flip the handedness of the coordinate system back to right handed.
ctm?.scaledBy(x: 1.0, y: -1.0)
var xformRect: CGRect? = nil
if let ctm = ctm {
xformRect = frameRect.applying(ctm)
}
let url = URL(string: text)
if let url = url {
UIGraphicsSetPDFContextURLForRect(url, xformRect ?? CGRect.zero)
}
context?.saveGState()
let attributesDict =[
.foregroundColor: UIColor.blue,
.underlineStyle: NSUnderlineStyle.single.rawValue
]
let attString = NSMutableAttributedString(string: url?.absoluteString ?? "", attributes: attributesDict as? [NSAttributedString.Key : Any])
attString?.draw(in: frameRect)
context?.restoreGState()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With