2017-05-03 27 views
1

NSView 캔버스에서 텍스트를 렌더링하려고합니다. 나는 3 줄의 글을 쓰고 넘어서는 것을 무시해야한다. String.draw (in : withAttributes)는 제공된 rect로 완벽하게 처리됩니다. 내 코드는 다음과 같습니다 조정없이NSView로 작성하기

func renderText(_ string:String, x:Double, y:Double, numberOfLines: Int, withColor color:Color) -> Double { 
    let font = NSFont.boldSystemFont(ofSize: 11) 
    let lineHeight = Double(font.ascender + abs(font.descender) + font.leading) 
    let textHeight = lineHeight * Double(numberOfLines) + font.leading // three lines 
    let textRect = NSRect(x: x, y: y, width: 190, height: textHeight) 
    string.draw(in: textRect, withAttributes: [NSFontAttributeName: font, NSForegroundColorAttributeName: color]) 
    return textHeight 
} 

renderText("Lorem ipsum...", x: 100, y: 100, numberOfLines: 3, withColor: NSColor.white) 

이 텍스트의 두 줄 렌더링, 내가 얻을 : 내가 뭔가를 놓친 거지 https://developer.apple.com/library/content/documentation/TextFonts/Conceptual/CocoaTextArchitecture/FontHandling/FontHandling.html#//apple_ref/doc/uid/TP40009459-CH5-SW18

:

enter image description here

것은 내가이 지침에 따라 무엇입니까?

+0

그건

내가 boundingRectWithSize 제안에 렌더링되는 CGContext의 규칙을 사용하여 텍스트의 경계를 찾으려면 응용 프로그램의 IOS 버전에서 이상한 방법, 동일한 코드 (UIFont 함께) 세 줄을 보여주는 잘 작동하는 것 같다. –

답변

2

궁극적으로 텍스트는 코코아의 텍스트 아키텍처를 구성하는 클래스를 호출하여 화면에 표시하므로이 클래스에서 직접 행 높이 정보를 얻는 것이 좋습니다. 아래의 코드에서 NSLayoutManager 인스턴스를 만들고 typesetter behavior 속성을 함수 drawInRect:withAttributes:에 의해 생성 된 기계에서 궁극적으로 사용되는 typesetter의 값과 일치하도록 설정합니다. 레이아웃 관리자의 defaultLineHeight 메소드를 호출하면 이후의 높이 값이 제공됩니다.

lazy var layoutManager: NSLayoutManager = { 
    var layoutManager = NSLayoutManager() 
    layoutManager.typesetterBehavior = .behavior_10_2_WithCompatibility 
    return layoutManager 
}() 

func renderText(_ string:String, x:Double, y:Double, numberOfLines: Int, withColor color:NSColor) -> Double { 
    let font = NSFont.boldSystemFont(ofSize: 11) 
    let textHeight = Double(layoutManager.defaultLineHeight(for: font)) * Double(numberOfLines) 
    let textRect = NSRect(x: x, y: y, width: 190, height: textHeight) 
    string.draw(in: textRect, withAttributes: [NSFontAttributeName: font, NSForegroundColorAttributeName: color]) 
    return textHeight 
} 
+0

완벽하게 작동합니다. 고맙습니다! :) –

1

textHeight에 작은 델타를 추가하려고합니다. Doubles가 완벽하게 정확합니다.

+0

세 번째 줄을 표시하려면 약 4 포인트 ('textHeight = ... + 4')를 추가해야합니다. 이것은 큰 차이입니다, 내 lineHeight 계산이 정확한지 알고 싶습니다. iOS 버전의 앱에서는 +4 조정이없는 동일한 코드가 iOS 시뮬레이터에서 작동하는 것 같습니다. –

+1

텍스트를 정확한 타이포그래피 범위로 작성하고 있지만 시스템에서 텍스트를보다 쉽게 ​​읽을 수 있도록 텍스트의 크기를 조정하여 화면 상에 표시 할 수 있습니다 (예 : 벡터 글꼴의 대체 화면 글꼴). 정확한 타이포그래피 범위를 사용하면 오름차순 또는 디 센더가 범위를 벗어나는 문자에 문제가 발생할 수 있습니다. 예를 들어, "A- 링"문자 또는 억음 악센트가있는 대문자 E. 특정 상황에서 텍스트의 높이를 측정 할 수있는 루틴을 찾아야합니다 ... 내 두뇌에서 내 두뇌를 리콜 할 수 있는지 확인합니다. –

+2

boundingRectWithSize : options : context : (NSAttributedString의 경우) 및 boundingRectWithSize : options : attributes : context : (NSString의 경우) –

2

당신은 정확한 인쇄상의 경계로 텍스트를 작성하지만, 시스템은 (벡터 폰트에 대한 예를 들어, 대체 화면 글꼴) 텍스트보다 읽기를 만들기 위해 화면에 프리젠 테이션을 위해 텍스트의 크기를 조정할 수 있습니다. 정확한 타이포그래피 범위를 사용하면 오름차순 또는 디 센더가 범위를 벗어나는 문자에 문제가 발생할 수 있습니다. 예를 들어, "A- 링"문자 또는 억음 악센트가있는 대문자 E. 옵션 : 문맥 : 및 boundingRectWithSize (NSAttributedString은 용) : 옵션 : 속성 : 컨텍스트 (있는 NSString에 대한)이