2010-01-02 85 views
11

我有一個多行UILabel,我想啓用放大功能。放大正確尺寸的UILabel&重新渲染字體

我有UIScrollView嵌入並分鐘變焦設置爲.25,最大變焦爲4。這工作得很好,但是我UILabel的字體看起來相當總值(GDP)比1

我可以在其他任何縮放級別處理這個方法:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale 

爲了重新大小我的UILabel的東西較大的字體,但認爲仍放大,所以它總是看起來很恐怖。

有什麼辦法讓標籤的文本重新渲染一個我完成縮放?

重要的是用戶當前滾動的文字在文字中的位置不會丟失。

(要了解我要做的事情,請注意如何在移動Safari中縮放文本時縮放/消除鋸齒時間,然後清理起來以您當前的縮放比例)

回答

16

UIScrollView的內置縮放比例只對您的內容視圖應用轉換,導致比例因子爲1.0以上的任何內容模糊不清。爲了真正的銳利渲染,你需要自己處理縮放。我在this answer中描述了一大塊過程。

您需要手動跟蹤內容視圖的比例因子,然後在-scrollViewDidEndZooming:withView:atScale:delegate方法中應用該比例。對於你的UILabel,這將意味着改變字體大小以反映新的比例。

爲了保持正確的滾動位置,您需要在上述委託方法中獲取UIScrollView的contentOffset並計算新縮放的UILabel中對應的位置。然後,您將滾動視圖的contentSize設置爲與UILabel的新大小相匹配,並使用-setContentOffset:animated:設置新計算的內容偏移量(動畫設置爲NO)。

獲得正確的數學有點棘手,但是當我在其中一個應用程序中縮放文本時可以這樣做,這可以在video demonstration of that application(大約1/3標記)處看到。

+0

感謝您的詳細解答。 這是否意味着我需要放棄scrollview的內置縮放功能? 或者當我完成縮放時,我只是重新渲染新比例因子的曲面? 這對您的最小/最大縮放設置有什麼影響? – 2010-01-02 18:25:49

+0

在捏手勢正在進行時使用內置縮放,然後在手勢完成時重新渲染。這是獲得體面的縮放縮放性能的唯一方法。 UIScrollView會跟蹤整體縮放比例(這就是爲什麼您需要重寫內容視圖上的轉換存取器以抵消這種情況),因此它仍然會觀察最小/最大縮放設置。 – 2010-01-02 21:39:36

+0

盯着更有意義。所以如果我縮放到150%,我可以將標籤的字體大小更改爲1.5 * currentFontSize,重新計算它們的確切滾動位置,然後重新渲染我的標籤。然後我將縮放重置爲1並重新計算我的最小/最大值?我有這個權利嗎? – 2010-01-04 19:33:56

0

還有就是做這個簡單的方法..

換上CATiledLayer的的UILabel的layerClass並設置適當的詳細程度。

+ (Class)layerClass 
{ 
    CATiledLayer *layerForView = (CATiledLayer *)self.layer; 
    layerForView.levelsOfDetailBias = 2; 
    layerForView.levelsOfDetail = 2; 
    return [CATiledLayer class]; 
} 

作業已完成

+0

崩潰對我來說... – jjxtra 2012-08-16 03:39:25

+0

您是否已經導入了QuarzCore? – JEzu 2012-08-29 16:29:04

+3

self.layer不會在類方法中工作。 – 2014-02-21 02:17:47

2

正確的方式來代替一的CALayer與CATiledLayer情況如下:

+ (Class)layerClass { 
    return [CATiledLayer class]; 
} 

分開,你已經設置你的偏見細節和你需要什麼。

7

謝謝valvoline & Scrimmers爲您的答案。我的解決方案是你的混合。

子類的UILabel這樣的:

UILabelZoomable.h

+ (Class) layerClass; 

UILabelZoomable.m

+ (Class) layerClass 
{  
    return [CATiledLayer class]; 
} 

現在,當你在你的應用程序中使用您的新奇UILabelZoomable,記得要做到這一點:

YourViewController.m

CATiledLayer *tiledLayer = (CATiledLayer*)textoLabel.layer; 
tiledLayer.levelsOfDetail = 10; 
tiledLayer.levelsOfDetailBias = 10; 

記得要添加QuartzCore框架!

#import <QuartzCore/QuartzCore.h> 

享受銳利和一個美麗的呈現的文字:

[UIView animateWithDuration:1 animations:^ 
    { 
     yourLabel.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(200, 200), CGAffineTransformMakeRotation(1)); 
    }]; 
+1

我崩潰... – jjxtra 2012-08-16 03:37:39

+0

最後一行怎麼回事? CGAffineTransformMakeRotation(1)將標籤旋轉1弧度左右。 – 2017-08-01 12:54:05

2

我的iOS 5.1和6測試版測試JEzu的代碼,它正在爲一個常量文本標籤,但導致其他正常的標籤需要更新文本內容失敗,即文字沒有改變...

我將UILabel作爲ZoomableLabel的子類與JEzu的答案,並將類應用爲標籤的自定義類,它工作正常。

7

iOS 4以上

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale { 
    scrollView.contentScaleFactor = scale; 
    for (UIView *subview in scrollView.subviews) { 
     subview.contentScaleFactor = scale; 
    } 
} 

如果過於密集,性能很慢,只是嘗試設置contentScaleFactor只有標籤。

+1

完美!這是最簡單的解決方案 – coolcool1994 2015-07-06 14:39:20

+0

沒有爲我工作。縮放後標籤仍然模糊不清。 – 2017-08-01 09:48:30

3

我實現了Scrimmers的解決方案,通過將UILabel作爲DetailedUILabel進行子類化,並使用像這樣的重寫方法;

進口QuartzCore

#import <QuartzCore/QuartzCore.h> 

覆蓋init方法,initWithFrame無論你想要的。

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     CATiledLayer *tiledLayer = (CATiledLayer *)self.layer; 
     tiledLayer.levelsOfDetailBias = 4; 
     tiledLayer.levelsOfDetail = 4; 
     self.opaque = YES; 
    } 
    return self; 
} 

and layerClass,class method。

+ (Class)layerClass { 
    return [CATiledLayer class]; 
} 
+0

這很棒!謝謝! – 2014-02-08 03:00:56

1

這裏是什麼,我想出了:

func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) { 
     label.font = UIFont(name: "YourFont", size: fontSize * scale) 
     label.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(1/scale, 1/scale), CGAffineTransformMakeRotation(0)) 
    } 

更新了雨燕4.0:

func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) { 
    label.font = label.font.withSize(fontSize * scale) 
    label.transform = CGAffineTransform(scaleX: 1/scale, y: 1/scale).concatenating(CGAffineTransform(rotationAngle: 0)) 
} 

還要記住的是,標籤應足夠大,以顯示整個文本。有時需要一點點重繪,但這種方法相當簡單。