あるCATextlayer
サイズのNSAttributedString
テキストと長さが不明なテキストがあります。
テキストがフレームに合うようにフォントサイズを調整する必要があります(その逆ではありません:)
どこから始めればいいですか?:)
[編集]nallが指摘しているように、文字列の長さを決定できます。もちろん、固定サイズのボックスに収める必要があるのは、ユーザーが入力したテキストです。
あるCATextlayer
サイズのNSAttributedString
テキストと長さが不明なテキストがあります。
テキストがフレームに合うようにフォントサイズを調整する必要があります(その逆ではありません:)
どこから始めればいいですか?:)
[編集]nallが指摘しているように、文字列の長さを決定できます。もちろん、固定サイズのボックスに収める必要があるのは、ユーザーが入力したテキストです。
Swift5クリーンソリューションのために働いています。
1)文字列を拡張する
extension String {
func size(OfFont font: UIFont) -> CGSize {
return (self as NSString).size(withAttributes: [NSAttributedString.Key.font: font])
}
}
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)コードに移動し、CATextLayerの代わりにDynamicTextLayerを使用します
textLayer = DynamicTextLayer()
textLayer?.alignmentMode = .center
textLayer?.fontSize = 40
textLayer?.string = "Example"
textLayer?.adjustsFontSizeToFitWidth = true
私はこれを行うことによってそれを達成しました:
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];
私はこれをすることになった:
textlayer
はCATextlayer
theString
はNSMutableAttributedString
そして、はい、それはあまりエレガントではなく、間違いなく改善される可能性があります;)
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;
}
CATextLayer *textLayer;
[textLayer setWrapped: TRUE];
これはうまくいけばうまくいくでしょう