2013-06-16 9 views
13

Czy możliwe jest rysowanie za pomocą prostych cieni tekstowych podczas korzystania z dodatków NIKtring UIKit? Mam na myśli to, że bez pisania kodu rysuję dwa razy w dwóch kolorach, tak jak w przypadku różnych klas UIKit, takich jak UILabel i jego własności shadowColor i shadowOffset, a także bez wykonywania faktycznych cieni przez CGContextSetShadow (które z pewnością będą znacznie droższe).Czy można narysować tekst z cieniami przy użyciu dodatków NIKtring UIKit?

Apple's doc for these extensions faktycznie należą stałe (na samym dole), w tym UITextAttributeTextShadowColor i UITextAttributeTextShadowOffset co oznacza, że ​​jest to możliwe, ale nie widzę żadnego możliwego wykorzystania ich w rzeczywistych metod.

Odpowiedz

29

Kilka myśli:

  1. The UITextAttributeTextShadow... klucze są przeznaczone przy użyciu słownika atrybutu tekstu z, na przykład, UIAppearance metody:

    NSDictionary *attributes = @{UITextAttributeTextShadowColor : [UIColor blackColor], 
              UITextAttributeTextShadowOffset : [NSValue valueWithUIOffset:UIOffsetMake(2.0, 0.0)], 
              UITextAttributeTextColor  : [UIColor yellowColor]}; 
    
    [[UINavigationBar appearance] setTitleTextAttributes:attributes]; 
    

    W UITextAttributeTextShadow... klucze są przeznaczone do użytku tylko w tych metodach, które akceptują słownik atrybutów tekstowych.

  2. Najbliższy odpowiednik klucz podczas rysowania ciągów tekstowych jest stosowanie przypisywanych strun z kluczem NSShadowAttributeName:

    - (void)drawRect:(CGRect)rect 
    { 
        UIFont *font = [UIFont systemFontOfSize:50]; 
    
        NSShadow *shadow = [[NSShadow alloc] init]; 
        shadow.shadowColor = [UIColor blackColor]; 
        shadow.shadowBlurRadius = 0.0; 
        shadow.shadowOffset = CGSizeMake(0.0, 2.0); 
    
        NSDictionary *attributes = @{NSShadowAttributeName   : shadow, 
               NSForegroundColorAttributeName : [UIColor yellowColor], 
               NSFontAttributeName   : font}; 
    
        NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:@"this has shadows" attributes:attributes]; 
    
        [attributedText drawInRect:rect]; 
    } 
    

    Jeśli jesteś zaniepokojony przeboju wydajności algorytmu cieni zdolny krzywą Beziera cień jednak może cierpieć z tego powodu. Ale wykonanie pewnych testów porównawczych, zmiana shadowBlurRadius dramatycznie wpływa na wydajność. Na przykład animacja rotacji złożonego tekstu wielowierszowego za pomocą wolniejszego iPhone'a 3GS z niezmienną liczbą klatek na sekundę wyniosła 31 fps, ale zmiana shadowBlurRadius na 0.0 przyniosła szybkość klatek 60 fps.

    Dolna linia, wykorzystująca promień rozmycia w cieniu 0.0, eliminuje większość (o ile nie wszystkie) obciążeń obliczeniowych cienia generowanego przez beziera.

  3. FYI, doświadczam podobną poprawę wydajności poprzez ustawienie wartości do 0.0blur dla CGContextSetShadow, podobnie jak przeżyłem z przypisywanego interpretację tekstu powyżej.

Konkluzja, nie sądzę, należy obawiać obliczeniowej napowietrznej cieni Beziera oparte na tak długo, jak używać promień rozmycia 0.0. Nie zdziwiłbym się, gdyby napisanie tekstu dwukrotnie, raz dla cienia i ponownie dla koloru pierwszego planu, może być nawet trochę bardziej wydajne, ale nie jestem pewien, czy różnica będzie widoczna. Ale nie znam żadnych wywołań API, które to zrobią (oprócz CGContextSetShadow z blur z 0.0).

+0

Dzięki! Nadal jestem zdumiony obecnością tych stałych cieni na dole [Apple doc for NSString UIKit Additions] (http://developer.apple.com/library/ios/#documentation/uikit/reference/NSString_UIKit_Additions/Reference /Reference.html), ale to musi być pomyłka z ich strony. Dobrze wiedzieć, że 0 rozmycia cienia nie są nieefektywne, jak na twoje doświadczenie! – Clafou

+0

@Clafou Być może nie podążam za twoim pytaniem, ale te stałe cienia są używane dla metod, które biorą "słownik atrybutów", jak na przykład metody 'UIAppearance', jak to zilustrowałem w moim pierwszym punkcie. Myślę, że to nie ma znaczenia, ponieważ nie uważam, że nie są one użyteczne dla twojego obecnego wyzwania, ale jeśli kiedykolwiek wejdziesz w "UIAppearance", użyjesz tych stałych. – Rob

+0

Mam na myśli, dlaczego Apple dokumentuje te stałe atrybutów tekstowych na stronie [NSString drawing methods] (http://developer.apple.com/library/ios/#documentation/uikit/reference/NSString_UIKit_Additions/Reference/Reference. html) (które nie używają tych atrybutów) zamiast na stronie [NSAttributedString] (http://developer.apple.com/library/ios/#documentation/uikit/reference/NSAttributedString_UIKit_Additions/Reference/Reference.html) (które używają ich jak na przykładowy kod)? – Clafou

2

Poniżej fragment wykorzystuje CALayer dodać cień wokół krawędzi znaków w UILabel:

_helloLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)]; 
[_helloLabel setBackgroundColor:[UIColor clearColor]]; 
[_helloLabel setTextColor:[UIColor whiteColor]]; 
[_helloLabel setTextAlignment:NSTextAlignmentCenter]; 
[_helloLabel setFont:[UIFont lightApplicationFontOfSize:30]]; 

_helloLabel.layer.shadowColor = UIColorFromRGB(0xd04942).CGColor; 
_helloLabel.layer.shadowOffset = CGSizeMake(0, 0); 
_helloLabel.layer.shadowRadius = 2.0; 
_helloLabel.layer.shadowOpacity = 1.0; 

[self addSubview:_helloLabel]; 

. . normalnie dodawałoby to cień wokół granicy, ale UILabel traktuje te właściwości jako specjalny przypadek.

+2

Dzięki Jasper!Rysuję bezpośrednio w kontekście graficznym za pomocą Core Graphics, a korzystanie z dodatków NIKtring UIKit jest bardzo przydatne. Osiągam coś podobnego do twojej odpowiedzi, dodając 'CGContextSetShadowWithColor (context, CGSizeMake (1.0f, -1.0f), 0.0f, [UIColor whiteColor] .CGColor);' przed moim rysowaniem, ale myślę, że jest to mniej efektywne niż shadowColor/shadowOffset rzecz, która jest implikowana przez stałe w dokumencie. – Clafou

+0

Och, fajne - nie zdawałem sobie sprawy, że jesteś na poziomie rysunku. . . dobra robota! –

Powiązane problemy