CTFrame иногда пуст в зависимости от UIFont pointSize - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь нарисовать приписанную строку в CGContext, используя Core Text.У меня есть интересная проблема, она работает для некоторых размеров шрифта, но не для других.CTFrame иногда пуст - visible string range = (0,0) - что означает, что установщик фреймов не мог разместить текст.Я понял, что это потому, что путь слишком мал, чтобы нарисовать текст в нем.Если я добавлю 10 к высоте в этом случае, то это работает.

Есть идеи, почему это будет?Как я могу получить размер, который должен быть, не меньше и не больше?

let fontSize: CGFloat = 191 //FIXME: 190 and 192 work, why not 191?
let attributedString = NSAttributedString(string: "Hello", attributes: [.font: UIFont.systemFont(ofSize: fontSize)])
let textSize = attributedString.size()

let rect = CGRect(origin: .zero, size: CGSize(width: 4000, height: 3000))
let positionX = rect.width - ceil(textSize.width) //right edge of rect
let path = CGPath(rect: CGRect(x: positionX, y: 0, width: ceil(textSize.width), height: ceil(textSize.height)/* + 10*/), transform: nil)

let framesetter = CTFramesetterCreateWithAttributedString(attributedString)
let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, attributedString.length), path, nil)
print(frame)

Результат этого где fontSize == 190:

<CTFrame: 0x600000598a80>{visible string range = (0, 5), path = <CGPath 0x600001f8fc50>, attributes = (null), lines = (
    "<CTLine: 0x60000039a670>{run count = 1, string range = (0, 5), width = 408.574, A/D/L = 180.908/45.8301/0, glyph count = 5, runs = (\n\n<CTRun: 0x7fdde391adf0>{string range = (0, 5), string = \"Hello\", attributes = {\n    NSFont = \"<UICTFont: 0x7fdde1c0fc20> font-family: \\\".SFUIDisplay\\\"; font-weight: normal; font-style: normal; font-size: 190.00pt\";\n}}\n\n)\n}"
)}

Результат этого где fontSize == 191:

<CTFrame: 0x600003e56bc0>{visible string range = (0, 0), path = <CGPath 0x60000240f0c0>, attributes = (null), lines = (
)}

1 Ответ

0 голосов
/ 28 февраля 2019

Ответ по телефону, извините за проблемы с форматированием.Используйте CTFramesetterSuggestFrameSizeWithConstraints вместо textSize из вашего кода.

 let attri = NSAttributedString(string: str, attributes: self.attributes(str: str, font: ft))
 let frameSetter = CTFramesetterCreateWithAttributedString((attri as CFAttributedString))
 var fitRange = CFRangeMake(0, 0)
 var fitRange = CFRangeMake(0, 0)
 let suggested = CTFramesetterSuggestFrameSizeWithConstraints(frameSetter, CFRangeMake(0,attri.length), nil, CGSize(width:bounds.width,height:.greatestFiniteMagnitude), &fitRange)
 path.addRect(CGRect(x: 0, y: 0, width: ceil(max(suggested.width, self.bounds.width)), height: ceil(max(suggested.height, self.bounds.height))))
 let ctFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0,attri.length), path, nil)


...