2016-03-25 16 views
5

Patrząc na dokumentacji NSLayoutManager, a konkretnie sposobu drawUnderlineForGlyphRange:underlineType:baselineOffset:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:, zauważyłem następujące (kopalnia nacisk):Jak zdefiniować niestandardowe NSUnderlineStyle

underlineVal
Styl podkreślając rysować. Ta wartość jest maską pochodzącą od wartości dla NSUnderlineStyleAttributeName - na przykład (NSUnderlinePatternDash | NSUnderlineStyleThick). Podklasy mogą definiować niestandardowe style podkreślania.

Moje pytanie brzmi: jak dokładnie to ma być zrobione?

NSUnderlineStyle to wyliczenie, którego nie można przedłużyć ani przesłonić. Można oczywiście zapewnić losową surowego Int wartość atrybutu, nieobjętych przypadkach ENUM:

self.addAttribute(NSUnderlineStyleAttributeName, value: 100022, range: lastUpdatedWordRange)

które wygłosi „nieważny”, ale użyteczny underlineType do układu Manger:

debugger screenshot

Ale to prawie nie czuje się bezpiecznie i jest zdecydowanie nieeleganckie.

Nie znalazłem żadnych przykładów online ani dalszych wskazówek w dokumentacji Apple na temat wyglądu mitycznych niestandardowych typów podkreślenia. Chciałbym wiedzieć, czy brakuje mi czegoś oczywistego.

+0

NSUnderlineStyle wydaje się słabo t eam gracza. Jest źle udokumentowany, a w Swift nadal nie został przekonwertowany na zestaw opcji. Czytając flagi w danym stylu, wydaje się niewiarygodny (albo robię coś źle). Chciałbym móc pomóc, ale wciąż szukam rozwiązania ... –

Odpowiedz

3

Mam projekt przykładem, że kiedyś na rozmowę na TextKit że dałem jakiś czas temu, że robi dokładnie to, czego szukasz: https://github.com/dtweston/text-kit-example

podkreślenia w tym przypadku jest zniekształcone linię:

underline screenshot

mięso roztworu jest niestandardowy NSLayoutManager:

let CustomUnderlineStyle = 0x11 

class UnderlineLayoutManager: NSLayoutManager { 

    func drawFancyUnderlineForRect(_ rect: CGRect) { 
     let left = rect.minX 
     let bottom = rect.maxY 
     let width = rect.width 

     let path = UIBezierPath() 
     path.move(to: CGPoint(x: left, y: bottom)) 
     var x = left 
     var y = bottom 
     var i = 0 
     while (x <= left + width) { 
      path.addLine(to: CGPoint(x: x, y: y)) 
      x += 2 
      if i % 2 == 0 { 
       y = bottom + 2.0 
      } 
      else { 
       y = bottom 
      } 
      i += 1; 
     } 

     path.stroke() 
    } 

    override func drawUnderline(forGlyphRange glyphRange: NSRange, underlineType underlineVal: NSUnderlineStyle, baselineOffset: CGFloat, lineFragmentRect lineRect: CGRect, lineFragmentGlyphRange lineGlyphRange: NSRange, containerOrigin: CGPoint) { 

     if underlineVal.rawValue & CustomUnderlineStyle == CustomUnderlineStyle { 

      let charRange = characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil) 
      if let underlineColor = textStorage?.attribute(NSUnderlineColorAttributeName, at: charRange.location, effectiveRange: nil) as? UIColor { 
       underlineColor.setStroke() 
      } 

      if let container = textContainer(forGlyphAt: glyphRange.location, effectiveRange: nil) { 
       let boundingRect = self.boundingRect(forGlyphRange: glyphRange, in: container) 
       let offsetRect = boundingRect.offsetBy(dx: containerOrigin.x, dy: containerOrigin.y) 

       drawFancyUnderlineForRect(offsetRect) 
      } 
     } 
     else { 
      super.drawUnderline(forGlyphRange: glyphRange, underlineType: underlineVal, baselineOffset: baselineOffset, lineFragmentRect: lineRect, lineFragmentGlyphRange: lineGlyphRange, containerOrigin: containerOrigin) 
     } 
    } 
} 
Powiązane problemy