Iphone 缩放标签&;以正确的大小重新呈现字体
我有一个多行Iphone 缩放标签&;以正确的大小重新呈现字体,iphone,uiscrollview,uilabel,Iphone,Uiscrollview,Uilabel,我有一个多行ui标签,我想启用缩放功能 我将它嵌入了一个UIScrollView,并将最小缩放设置为.25,最大缩放设置为4。这很好,但是myUILabel的字体在除1以外的任何缩放级别上看起来都相当粗糙 我可以处理这种方法: - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale 为了将UILabel的字体重新调整为更大的字体,但视图仍在放大
ui标签
,我想启用缩放功能
我将它嵌入了一个UIScrollView
,并将最小缩放设置为.25,最大缩放设置为4。这很好,但是myUILabel
的字体在除1以外的任何缩放级别上看起来都相当粗糙
我可以处理这种方法:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
为了将UILabel的字体重新调整为更大的字体,但视图仍在放大,因此看起来总是很糟糕
缩放完成后,有没有办法使标签的文本重新呈现
重要的是,用户当前在文本中的滚动位置不会丢失
(要了解我的意图,请注意,在Mobile Safari中,当您缩放文本时,文本会在瞬间缩放/消除锯齿,然后它会清除,以在当前缩放比例下渲染良好)UIScrollView的内置缩放功能仅对内容视图应用变换,这会导致比例因子大于1.0时出现模糊。对于真正的锐利渲染,您需要自己处理缩放。我在中描述了这一过程的一部分 您需要手动跟踪内容视图的比例因子,然后在-ScrollViewDiEndZooming:withView:atScale:delegate方法中应用该比例。对于UILabel,这意味着更改字体大小以反映新的比例 为了保持正确的滚动位置,您需要在上述委托方法中获取UIScrollView的contentOffset,并计算新缩放的UILabel中对应的位置。然后,将滚动视图的contentSize设置为与UILabel的新大小相匹配,并使用-setContentOffset:animated:设置新计算的内容偏移量(将animated设置为NO)
正确的数学运算有点棘手,但我在我的一个应用程序中缩放文本时会这样做,这可以在中看到(大约1/3处)。有一种更简单的方法可以做到这一点 将UILabel的layerClass替换为CATiledLayer,并适当设置详细程度
+ (Class)layerClass
{
CATiledLayer *layerForView = (CATiledLayer *)self.layer;
layerForView.levelsOfDetailBias = 2;
layerForView.levelsOfDetail = 2;
return [CATiledLayer class];
}
完成作业用CATiledLayer替换CALayer的正确方法如下:
+ (Class)layerClass {
return [CATiledLayer class];
}
除此之外,你还需要设置你的偏见细节和你需要的任何东西。感谢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>
我在iOS 5.1和6 beta版中测试了JEzu的代码,它适用于常量文本标签,但导致其他正常标签要求更新文本内容失败,即文本未更改 我使用JEzu的答案将UILabel子类化为ZoomableLabel,并将该类应用为标签的自定义类,它运行良好。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。我通过将UILabel子类化为DetailedUILabel,并使用如下重写方法实现Scrimmers的解决方案 进口石英砂
#import <QuartzCore/QuartzCore.h>
和layerClass,类方法
+ (Class)layerClass {
return [CATiledLayer class];
}
以下是我想到的:
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))
}
还要记住,标签应该足够大,以显示整个文本。重画有时需要一点时间,但这种方法相当简单。感谢您提供的详细答案。这是否意味着我需要放弃scrollview的内置缩放功能?或者当我完成缩放后,我只是以新的比例因子重新渲染曲面?这对最小/最大缩放设置有什么影响?在按住手势时使用内置缩放,然后在手势完成时重新渲染。这是获得良好缩放性能的唯一方法。UIScrollView跟踪整体缩放比例(这就是为什么您需要覆盖内容视图上的变换访问器以抵消此影响),因此它仍将观察最小/最大缩放设置。开始了解更多信息。因此,如果缩放到150%,我可以将标签的字体大小更改为1.5*currentFontSize,重新计算它们的精确滚动位置,然后重新渲染标签。然后我将缩放重置为1并重新计算最小/最大值?我有这个权利吗?这是令人惊讶的好东西,显然你是唯一一个发表过关于这方面的文章的人(这里是SO:)@Yar-很高兴这是有用的。您可能想查看我添加到链接答案中的更新,因为iPhone OS 3.2+中的某些缩放行为发生了更改。太棒了!这是最简单的解决方案,但对我不起作用。缩放后标签仍然模糊。最后一行是怎么回事?CGAffineTransformMakeRotation(1)将标签旋转1弧度。这是我解决此问题的首选方法,但您不需要仿射旋转变换(
CGAffineTransform(rotationAngle:0)
)。
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))
}
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))
}