【问题标题】:Rendering content after zoomed in for UIScrollView为 UIScrollView 放大后渲染内容
【发布时间】:2011-10-05 18:23:37
【问题描述】:

我环顾四周,似乎人们说您可以在放大后重新渲染数据,因为您知道 UIScrollView 的比例因子。我还看过一些关于将图层设置为 CATiledLayer 并设置levelsOfDetailBias 和levelsOfDetail 的帖子。

我拥有的是一个 UIScrollView,其中还有一个 ResultsView,它是 UIView 的一个子类:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        CATiledLayer *tiledLayer = (CATiledLayer *)self.layer;
        tiledLayer.levelsOfDetailBias = 3;
        tiledLayer.levelsOfDetail = 3;
        self.opaque = YES;
    }
    return self;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

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

在我有 UIScrollView 和 ResultsView 的课堂上,我会这样做:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return self.ResultsView;
}

这足以让文本重新渲染(清晰)吗?还是我需要在

中实现一些东西
 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
 }

如果是这样,我不知道该怎么做。在我的 UIScrollView 和 ResultsView 类中,在 ResultsView(在 XIB 中)中,我只有几个 UILabel 和 UIView(用于视图的标题/页脚的 UIView)。所以我不知道如何从 ResultsView 重绘那些。虽然 ResultsView 在 XIB 中有 UILabels 和 UIViews 作为它的子项,但我不确定如何从 ResultsView 类中重绘它们,以及无论如何我需要做什么。

或者这是错误的方法?我是否只需要通过 scrollViewDidEndZooming: 委托方法中的比例因子调整 UILabel 和 UIView 的大小? TIA

【问题讨论】:

    标签: iphone


    【解决方案1】:

    我认为你采取了错误的方法。如果您的视图由不执行任何自定义绘图的 UILabel 和 UIViews 组成,我不会使用 CATiledLayer 支持的视图。而是实现 scrollViewDidEndZooming:withView:atScale: 委托方法并执行以下操作:

    - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
        scale *= [[[self.scrollView window] screen] scale];
        [view setContentScaleFactor:scale];
        for (UIView *subview in view.subviews) {
            [subview setContentScaleFactor:scale];
        }
    }
    

    【讨论】:

    • 谢谢。它工作得很好。我不认为我自己会找到这种类型的答案。您能解释一下为什么需要第一行 scale*=... 窗口/屏幕/比例返回的值对于设备会有所不同吗?谢谢。
    • 是的,这使它与视网膜显示兼容。在 iPad 和非 Retina 显示屏 iPhone/iPod touch 上,窗口屏幕比例为 1.0,因此没有效果。在视网膜显示器上,它是 2.0,因此它可以正确调整这些显示器的比例。
    • 一种更简洁的方法可能是使您正在缩放的​​视图成为 UIView 的子类(如果还没有)并创建一个方法来告诉每个子视图直接更新其 contentScaleFactor 而不是循环遍历所有子视图。如果您确实有一些可以自定义绘图的子视图,它将为您提供更细粒度的控制,因为您也希望在这些子视图上调用 setNeedsDisplay。
    • @afarnham 如何在 swift 中实现相同的矢量化结果?
    【解决方案2】:

    我有一些小东西要添加到公认的解决方案中,这给我带来了几分钟的痛苦,以防万一其他人遇到同样的事情。

    循环浏览您正在缩放的​​视图中的所有子视图并调用 setContentScaleFactor 不会考虑任何子视图本身是否具有子视图。如果您有这样更复杂的设置,请确保还遍历这些容器视图的子视图并调用

    [subview setContentScaleFactor:scale];
    

    每个。我创建了一个方法,我可以调用该方法在给定视图的所有子视图上调用 setContentScaleFactor,并为屏幕上的每个“容器视图”调用它。

    - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale 
    {
        scale *= [[[self.scrollView window] screen] scale];
        [view setContentScaleFactor:scale];
        for (UIView *subview in view.subviews) 
        {
            [self setContentSizeForView:subview andScore:scale];
    
            //Loop through all the subviews inside the subview
            for(UIView *subSubview in subview.subviews)
            {
                [self setContentSizeForView:subSubview andScale:scale];
            }
        }
    }
    
    - (void) setContentSizeForView:(UIView*) view andScale:(float)scale
    {
        [view setContentScaleFactor:scale];
    }
    

    【讨论】:

    • 我还需要打其他电话吗?当我将 UIView 子类的 contentScaleFactor(视图用于绘制和缩放)设置为等于(UIScrollView 委托方法的)比例值时,我的应用程序变得非常缓慢并崩溃。
    • 是的,当有很多子视图时,我还注意到这是一个非常缓慢的操作。我最终放弃了锐化内容,同时缩放复杂的视图/子视图层次结构,因为它太慢了。
    • 为什么不粘贴你做的方法?
    • @RaduSimionescu - 因为它很长并且特定于我的实现。另外,请参阅我之前的评论 - 我最终放弃了这个,因为它非常非常慢,而且很可能是一个糟糕的解决方案。对不起。
    • 这实际上是Apple打算为此类功能实现的解决方案
    猜你喜欢
    • 1970-01-01
    • 2016-02-01
    • 1970-01-01
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多