Reputation: 437
Just like the headline ,I have some Objective-c code ,how can I use them in Swift3
CGContextSaveGState(context);
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
CGContextTranslateCTM(context, 0, size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0, 0, size.width, size.height));
NSMutableAttributedString *attri = [[NSMutableAttributedString alloc]initWithString:_text];
[attri addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:10] range:NSMakeRange(0, _text.length)];
CTFramesetterRef ctFramesetting = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attri);
CTFrameRef ctFrame = CTFramesetterCreateFrame(ctFramesetting, CFRangeMake(0, attri.length), path, NULL);
CTFrameDraw(ctFrame, context);
CFRelease(path);
CFRelease(ctFramesetting);
CFRelease(ctFrame);
Upvotes: 3
Views: 5009
Reputation: 2443
Here's a clean Swift 3
version:
context.saveGState()
context.textMatrix = CGAffineTransform.identity
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
let path = CGMutablePath()
let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
path.addRect(rect, transform: .identity)
let attrString = NSMutableAttributedString(string: _text as String)
attrString.addAttribute(NSFontAttributeName,
value: UIFont.systemFont(ofSize: 10.0),
range: NSRange(location: 0,
length: _text.length))
let ctFramesetting = CTFramesetterCreateWithAttributedString(attrString)
let ctFrame = CTFramesetterCreateFrame(ctFramesetting,
CFRangeMake(0, attrString.length),
path,
nil)
CTFrameDraw(ctFrame, context)
I advise you not to use converters.
Why? With converters you'll
this means you'll get unstable/dirty code that you need to refactor
Upvotes: 4
Reputation: 3556
You can use something like the Objective-C to Swift Converter to get code like the following:
context.saveGState()
context.textMatrix = CGAffineTransform.identity
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
var path: CGMutablePathRef = CGMutablePath()
path.addRect(CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(size.width), height: CGFloat(size.height)), transform: .identity)
var attri = NSMutableAttributedString(string: _text)
attri.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: CGFloat(10)), range: NSRange(location: 0, length: _text.length))
var ctFramesetting: CTFramesetterRef? = CTFramesetterCreateWithAttributedString((attri as? CFAttributedStringRef))
var ctFrame: CTFrameRef = CTFramesetterCreateFrame(ctFramesetting, CFRangeMake(0, attri.length), path, nil)
CTFrameDraw(ctFrame, context)
But I would suggest that you do learn the underlying principles of both Objective-C and Swift so that you can do this sort of conversion yourself instead of relying on others or an external tool :)
For example, the above is the code as it came out from the converter. However, if you were to do some clean up, it would look something like this:
guard let context = UIGraphicsGetCurrentContext() else {
return
}
context.saveGState()
context.textMatrix = CGAffineTransform.identity
context.translateBy(x: 0, y: size.height)
context.scaleBy(x:1.0, y: -1.0)
let path = CGMutablePath()
path.addRect(CGRect(x:0, y:0, width:size.width, height:size.height), transform:.identity)
let attri = NSMutableAttributedString(string:_text as String)
attri.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize:10), range: NSRange(location: 0, length:_text.length))
let ctFramesetting = CTFramesetterCreateWithAttributedString(attri)
let ctFrame = CTFramesetterCreateFrame(ctFramesetting, CFRangeMake(0, attri.length), path, nil)
CTFrameDraw(ctFrame, context)
As you'll notice the following has to be added to get a CGContext
instance:
guard let context = UIGraphicsGetCurrentContext() else {
return
}
Also, some variables which were marked as mutable (or var
) have been changed to immutable (or let
) instances.
But that's not all there is to it. The above code assumes that _text
is of type NSString
. In order to use native Swift types, you should really change it to use String
instead of NSString
. Then the code changes to:
guard let context = UIGraphicsGetCurrentContext() else {
return
}
context.saveGState()
context.textMatrix = CGAffineTransform.identity
context.translateBy(x: 0, y: size.height)
context.scaleBy(x:1.0, y: -1.0)
let path = CGMutablePath()
path.addRect(CGRect(x:0, y:0, width:size.width, height:size.height), transform:.identity)
let attri = NSMutableAttributedString(string:_text)
attri.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize:10), range: NSRange(location: 0, length:_text.characters.count))
let ctFramesetting = CTFramesetterCreateWithAttributedString(attri)
let ctFrame = CTFramesetterCreateFrame(ctFramesetting, CFRangeMake(0, attri.length), path, nil)
CTFrameDraw(ctFrame, context)
So, in order to convert the code to Swift 3 and to make it work, you do need to understand the differences between Swift and Objective-C.
Upvotes: -1