xcode CATextlayer 更改 FONT 的大小以适合框架
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11059061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CATextlayer change size of FONT to fit the frame
提问by Swissdude
I have a CATextlayer
of a certain size and NSAttributedString
text of unknown length.
我有一个CATextlayer
特定大小和NSAttributedString
未知长度的文本。
I need to adjust the font-size so the text fits the frame (not vice versa :)
我需要调整字体大小,使文本适合框架(反之亦然:)
Any ideas where to start? :)
任何想法从哪里开始?:)
[Edit] as nall points out, I can determine the string length, of course, it's some text entered by the user that I need to fit into a box of fixed size.
[编辑] 正如 nall 指出的那样,我可以确定字符串长度,当然,这是用户输入的一些文本,我需要适合固定大小的框。
采纳答案by Swissdude
I ended up doing this:
我最终这样做了:
textlayer
is a CATextlayer
textlayer
是一个 CATextlayer
theString
is a NSMutableAttributedString
theString
是一个 NSMutableAttributedString
And yes, it's not very elegant and could definitely be improved ;)
是的,它不是很优雅,绝对可以改进;)
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)theString);
CGRect columnRect = CGRectMake(0, 0 , 320, 150);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, columnRect);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRange frameRange = CTFrameGetVisibleStringRange(frame);
int fontSize = 18;
while(theString.string.length > frameRange.length){
fontSize--;
CFStringRef fontName = (__bridge CFStringRef)[defs objectForKey:@"font"];
CTFontRef font = CTFontCreateWithName(fontName, fontSize, NULL);
[theString addAttribute:(NSString *)kCTFontAttributeName
value:(__bridge id)font
range:NSMakeRange(0, theString.string.length)];
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)theString);
CGRect columnRect = CGRectMake(0, 0 , 320, 150);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, columnRect);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
frameRange = CTFrameGetVisibleStringRange(frame);
textLayer.string = theString;
}
回答by Ricardo Ruiz Romero
I achieved it by doing this:
我通过这样做实现了它:
float fontSize = InitialFontSize;
UIFont *myFont = [UIFont boldSystemFontOfSize:fontSize];
CGSize myFontSize = [YourTextHere sizeWithFont:myFont];
while (myFontSize.width >= MaximunWidth) {
fontSize -= 0.1f;
myFont = [UIFont boldSystemFontOfSize:fontSize];
myFontSize = [YourTextHere sizeWithFont:myFont];
}
CATextLayer *textLayer = [CATextLayer layer];
[textLayer setFrame:CGRectMake(MaximunWidth - myFontSize.width / 2, MaximunHeight - myFontSize.height / 2, myFontSize.width, myFontSize.height)];
[textLayer setFontSize:fontSize];
[textLayer setString:YourTextHere];
[textLayer setAlignmentMode:kCAAlignmentCenter];
回答by Nick
Working for Swift 5clean solution.
为Swift 5清洁解决方案工作。
1) Extend String
1) 扩展字符串
extension String {
func size(OfFont font: UIFont) -> CGSize {
return (self as NSString).size(withAttributes: [NSAttributedString.Key.font: font])
}
}
2) Subclass the CATextLayer
2) 继承 CATextLayer
class DynamicTextLayer : CATextLayer {
var adjustsFontSizeToFitWidth = false
override func layoutSublayers() {
super.layoutSublayers()
if adjustsFontSizeToFitWidth {
fitToFrame()
}
}
func fitToFrame(){
// Calculates the string size.
var stringSize: CGSize {
get { return (string as? String)!.size(OfFont: UIFont(name: (font as! UIFont).fontName, size: fontSize)!) }
}
// Adds inset from the borders. Optional
let inset: CGFloat = 2
// Decreases the font size until criteria met
while frame.width < stringSize.width + inset {
fontSize -= 1
}
}
}
3) Now go to your code and instead of CATextLayer use DynamicTextLayer
3)现在转到您的代码,而不是 CATextLayer 使用 DynamicTextLayer
textLayer = DynamicTextLayer()
textLayer?.alignmentMode = .center
textLayer?.fontSize = 40
textLayer?.string = "Example"
textLayer?.adjustsFontSizeToFitWidth = true
回答by Ranjeet Singh
CATextLayer *textLayer;
[textLayer setWrapped: TRUE];
This will hopefully will work
这有望奏效