我想要启用放大的多行UILabel
。
我用UIScrollView
嵌入它并将最小缩放设置为.25,最大缩放设置为4.这很有效,但是UILabel
的字体看起来相当粗糙,除了1以外的任何缩放级别
我可以处理这个方法:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
为了将我的UILabel的字体重新调整为更大的尺寸,但视图仍然放大,所以它看起来总是很糟糕。
有没有办法让标签的文字重新渲染一个我完成缩放?
用户当前在文本中滚动的位置非常重要。
(为了了解我的目标,请注意在移动浏览器中缩放文本时如何缩放/消除锯齿一瞬间然后它会清除以在当前缩放比例下渲染得很好)< / p>
答案 0 :(得分:16)
UIScrollView的内置缩放仅将变换应用于内容视图,这会导致比例因子1.0以上的任何变化模糊。对于真正清晰的渲染,您需要自己处理缩放。我在this answer中描述了一大块过程。
您需要手动跟踪内容视图的比例因子,然后在-scrollViewDidEndZooming:withView:atScale:委托方法中,您将应用该比例。对于你的UILabel,这意味着要改变字体大小以反映新的比例。
为了保持正确的滚动位置,您需要在上面的委托方法中获取UIScrollView的contentOffset,并计算新缩放的UILabel中对应的位置。然后设置滚动视图的contentSize以匹配UILabel的新大小,并使用-setContentOffset:animated:设置新计算的内容偏移量(动画设置为NO)。
正确地计算数学有点棘手,但我在我的一个应用程序中缩放文本时会这样做,这可以在video demonstration of that application中看到(大约1/3标记)。
答案 1 :(得分:8)
感谢valvoline&amp; 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));
}];
答案 2 :(得分: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。
答案 3 :(得分: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;
}
和layerClass,类方法。
+ (Class)layerClass {
return [CATiledLayer class];
}
答案 4 :(得分:3)
以下是我提出的问题:
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))
}
针对Swift 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))
}
还要记住标签应该足够大以显示整个文本。它有时需要一点点重绘,但这种方法相当简单。
答案 5 :(得分:2)
使用CATiledLayer替换CALayer的正确方法如下:
+ (Class)layerClass {
return [CATiledLayer class];
}
除此之外,你必须设置你的偏见细节以及你需要的任何东西。
答案 6 :(得分:2)
我在iOS 5.1和6 beta中测试了JEzu的代码,它适用于const文本标签,但导致其他正常标签需要更新文本内容失败,即文本未更改...
我使用JEzu的答案将UILabel子类化为ZoomableLabel,并将该类应用为标签的自定义类,并且它可以正常工作。
答案 7 :(得分:1)
有一种更简单的方法可以做到这一点..
用CATiledLayer替换UILabel的layerClass并适当设置细节级别。
+ (Class)layerClass
{
CATiledLayer *layerForView = (CATiledLayer *)self.layer;
layerForView.levelsOfDetailBias = 2;
layerForView.levelsOfDetail = 2;
return [CATiledLayer class];
}
完成工作