2010-01-02 76 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)) 
} 

还要记住的是,标签应足够大,以显示整个文本。有时需要一点点重绘,但这种方法相当简单。