2014-04-19 1 views
2

나는 thisthis을 읽었지만 문제를 해결하지 못하는 것 같습니다."도난당한"UILabel의 레이어를 다른 CALayer의 하위 레이어에 추가하는 것이 안전합니까?

- (NSAttributedString *) attributedStringForText: (NSString *) text { 
    NSMutableAttributedString* attrStr = [[NSMutableAttributedString alloc] initWithString:text]; 
    UIFont * bigF = [UIFont fontWithName:@"OpenSans-Extrabold" size:20.0f] ; 
    UIFont * smaF = [UIFont fontWithName:@"OpenSans-Extrabold" size:12.0f] ; 

    [attrStr addAttribute:NSFontAttributeName value:bigF range:(NSRange){0, 3}] ; 
    [attrStr addAttribute:NSFontAttributeName value:smaF range:(NSRange){3, 6}] ; 
    [attrStr addAttribute:NSFontAttributeName value:bigF range:(NSRange){6, [text length]-6}] ; 

    [attrStr addAttribute:NSBackgroundColorAttributeName value:[UIColor brownColor] range:(NSRange){3, 6}] ; 
    return attrStr ; 
} 

- (CALayer *) stealLayerFromUILabelForText: (NSString *) text inRect: (CGRect) bounds { 
    UILabel * label = [[UILabel alloc] initWithFrame:bounds] ; 
    label.textColor = [UIColor whiteColor] ; 
    label.font = [UIFont fontWithName:@"OpenSans-Extrabold" size:20.0f] ; 
    label.attributedText = [self attributedStringForText:text] ; 
    [label sizeToFit] ; 
    [label.layer display] ; // Yup! 
    return label.layer ; 
} 

- (void) setupLayer: (CALayer *) tileLayer 
       text: (NSString *) text 
       index: (NSUInteger) index { 

    CGRect (^center_rect)(CGRect, CGRect) = ^CGRect (CGRect r, CGRect into) { 
     CGRect centered = into ; 
     centered.origin.x += (into.size.width - r.size.width)/2.0f ; 
     centered.origin.y += (into.size.height - r.size.height)/2.0f ; 
     centered.size = r.size ; 
     return centered ; 
    } ; 

    CALayer * layer = [self stealLayerFromUILabelForText:text inRect:tileLayer.bounds] ; 
    CGRect frame = center_rect(layer.bounds, tileLayer.bounds) ; 

    [tileLayer addSublayer:layer] ; 

    layer.frame = frame ; 
} 

을이 작동 :

enter image description here

그리고 this에 대한 답변은 고려

... NSCoding과 친구들의 접선을 이동하는 것, 그래서

하지만 나는 어떻게 든 UILabel을 학대합니다 & CALayer. 한편 UIView, UILabel 모두는 실제CALayer 계층 구조의 상단에 바로 얇은 터치 인식 베니어 있습니다. OTOH 나는 어쨌든 여기에 명시된 가정조차 거의 사용하지 않고있다.

누구나 이것이 더 이상 길을 깨는 이유를 알 수 없으며 그렇지 않은 경우 더 나은 증거가 될 수 있습니다.

+1

[CALayer display]의 첫 번째 줄에는 "이 방법을 직접 호출하지 마십시오."라는 것이 있습니다. 즉, 애플이 미래에 무언가를 바꾸면 깨질 수 있습니다. 아마도 가능성은 없지만 확실히 가능할 수 있습니다. – nsdebug

+0

'iOS Core Animation : Advanced Techniques Nick Lockwood'의 사례가 있습니다. http://books.google.co.uk/books?id=QfhdAAAAQBAJ&pg=PT117&lpg=PT117&dq=we+should+really+derive+these+ + UILabel + 설정 + 너무 +하지만 + % 27s + 복잡, + so + for + now + 우리는 % 27ll + just + hard-code + 그들을 & 소스 = bl & ots = zw23tDc5QeUYABIBtAVMg2eEQCc & hl = en & sa = X & ei = 55dSU_jNNMWjO-ntgNgL & = 0CC8Q6AEwAA # v = onepage & q = 우리 % 20 실제로 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % 20 % % 20them & f = false ... – verec

+1

iOS 7의 스냅 샷 API를 사용할 수 있습니다 – Felix

답변

1

2013 년부터이 기술을 사용해 왔지만 여전히 안정적입니다. 그래서 네, 지금은 안전하다고 생각합니다. 이전에는 iOS 4 또는 5에서 더 이상 최신 SDK에 대해 컴파일 할 때 작동하지 않는 ddplay를 호출하지 않고이 작업을 수행 했으므로이 재미있는 자료를 보내 주셔서 감사합니다. 이 기술은 여전히 ​​아이폰 OS 10에서 작동 Add text to CALayer

0

IMO (이 경우 UILabel의 단위)의 UIView 그래서, 단순히 백업의 CALayer의 대리자입니다 : 다른 옵션을 찾고 있다면

더 많은 정보는 이곳이 기본 CALayer를 직접 조작하는 것이 안전해야합니다. 유일한 문제는 레이블을 하위보기로 추가하지 않으면 레이블이 해제되고 기본 layer.delegate가 0이되고 텍스트가 렌더링 될 기회를 얻지 못할 때입니다.

그래서 레이블이 해제되기 전에 강제로 렌더링하는 방법이 필요합니다. 그러나 [CALayer display]을 Apple의 설명서에 따라 직접 호출하면 안됩니다. 그래서 같은 생각을 바탕으로 안전한 대안 인 [CALayer displayIfNeeded]을 고려하십시오.

- (CALayer *) stealLayerFromUILabelForText: (NSString *) text inRect: (CGRect) bounds { 
    UILabel * label = [[UILabel alloc] initWithFrame:bounds] ; 
    label.textColor = [UIColor whiteColor] ; 
    label.font = [UIFont fontWithName:@"OpenSans-Extrabold" size:20.0f] ; 
    label.attributedText = [self attributedStringForText:text] ; 
    [label sizeToFit] ; 
    [label.layer displayIfNeeded] ; 
    return label.layer ; 
}