代码之家  ›  专栏  ›  技术社区  ›  Ben Scheirman

缩放uiLabel并以正确的大小重新呈现字体

  •  13
  • Ben Scheirman  · 技术社区  · 15 年前

    我有多条线 UILabel 我想启用缩放。

    我嵌入了一个 UIScrollView 并将“最小缩放”设置为.25,将“最大缩放”设置为4。这很好用,不过我的 乌拉贝尔 在任何缩放级别(而不是1)上,其字体看起来都很粗糙。

    我可以处理这个方法:

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

    为了将我的uilabel字体重新调整为更大的字体,但是视图仍然放大,所以它看起来总是很糟糕。

    有没有办法让标签的文本重新呈现一个我已经完成缩放的文本?

    重要的是,用户当前在文本中的滚动位置不会丢失。

    (要了解我要做的是什么,请注意在Mobile Safari中,当您缩放文本时,文本会被缩放/消除混叠一秒,然后它会被清除,以便在当前的缩放比例下呈现良好效果)

    8 回复  |  直到 7 年前
        1
  •  16
  •   Community CDub    8 年前

    uiscrollview的内置缩放仅对内容视图应用转换,这会导致比例因子1.0以上的任何内容都变得模糊。要获得真正清晰的渲染效果,您需要自己处理缩放。我描述了一个过程 this answer .

    您需要手动跟踪内容视图的比例因子,然后在-ScrollViewDidendZooming:WithView:Atscale:Delegate方法中应用该比例。对于uilabel,这意味着更改字体大小以反映新的比例。

    为了保持正确的滚动位置,您需要在上面的委托方法中获取uiScrollView的ContentOffset,并计算新缩放的uiLabel中对应的位置。然后,将滚动视图的ContentSize设置为与uiLabel的新大小匹配,并使用-setContentOffset:animated:设置新计算的内容偏移量(将animated设置为no)。

    要使数学正确是有点困难的,但是当我在一个应用程序中缩放文本时,我会这样做,可以在 video demonstration of that application (大约在1/3处)。

        2
  •  8
  •   JEzu    12 年前

    感谢Valvoline&Scrimmersh为您提供答案。我的解决方案是你的混合方案。

    uilabel子类如下:

    可缩放uilabelzoomable.h

    + (Class) layerClass;
    

    可缩放uilabelzoomable.m

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

    现在,当你在你的应用程序中使用你喜欢的新的uilabelzoomable时,记住要这样做:

    你的视图控制器.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));
         }];
    
        3
  •  7
  •   kabucey    12 年前

    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。

        4
  •  3
  •   Eralp Karaduman    11 年前

    我通过将uilabel子类化为detaileduilabel,并使用类似这样的重写方法实现了scrinmersh的解决方案;

    进口夸脱

    #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方法。

    + (Class)layerClass {
        return [CATiledLayer class];
    }
    
        5
  •  3
  •   robinCTS    7 年前

    以下是我的一些想法:

    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))
    }
    

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

        6
  •  2
  •   valvoline    13 年前

    用阳离子层代替炉管的正确方法如下:

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

    另外,你必须设定你的偏见细节和你需要的任何东西。

        7
  •  2
  •   BillChan    12 年前

    我在iOS 5.1和6测试版中测试了Jezu的代码,它适用于常量文本标签,但由于其他普通标签要求更新文本内容失败,即文本没有更改…

    我用jezu的答案将uilabel子类化为zoomablelabel,并将该类应用于标签的自定义类,它工作正常。

        8
  •  1
  •   Scrimmers    14 年前

    有一种更简单的方法可以做到。

    将uilabel的layerClass替换为catiledLayer,并适当设置细节级别。

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

    作业已完成