繁体   English   中英

加快-drawRect:UIView子类的方法

[英]Speed up -drawRect: method for UIView subclass

我创建了一个自定义UIView子类。 一切在模拟器上都可以正常运行,但是在设备上却非常慢。 我的-drawRect:方法大约需要100毫秒才能完全重绘视图。

当我向该视图添加平移手势时出现了速度问题,并且在拖动时,该视图需要每秒重绘多次。

我需要优化drawRect:方法。 这是我当前的-drawRect:方法代码:

- (void)loayoutSubviews
{
    for (UIView* subview in self.subviews)
    {
        [subview removeFromSuperview];
    };

    // ...
    // some calculations here... assume that they can not be optimized
    // ...

    for (unsigned int blockCounter=0; blockCounter<blockQuantity; blockCounter++)
    {
        NSNumber *y=[blockTops objectAtIndex:blockCounter];
        NSNumber *height=[blockHeights objectAtIndex:blockCounter];

        if ([height intValue]>2)
        {
            if ([y doubleValue]>self.frame.size.height/2.0)
            {
                double angle= [[self angleValueForBlockHeight:height] doubleValue];

                UIView *bView=[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[blocks objectAtIndex:blockCounter]]];
                [bView setFrame:CGRectMake(0.0, [y doubleValue], self.frame.size.width, blockSize.height)];
                [bView.layer setMasksToBounds:YES];


                double oldHeight=bView.frame.size.height;

                [bView.layer setAnchorPoint:CGPointMake(0.5, 1.0)];
                [bView setFrame:CGRectMake(bView.frame.origin.x, bView.frame.origin.y+bView.frame.size.height/2.0, bView.frame.size.width, bView.frame.size.height)];

                if ([height doubleValue]!=blockSize.height)
                {
                    //preparing transform
                    CATransform3D basicTrans = CATransform3DIdentity;
                    basicTrans.m34 =1.0/-projection;

                    double rangle;
                    rangle=angle/360*(2.0*M_PI);

                    bView.layer.transform = CATransform3DRotate(basicTrans, rangle, 1.0f, 0.0f, 0.0f);

                };



                double newHeight=bView.frame.size.height;

                [bView setCenter:CGPointMake(bView.center.x, bView.center.y-(oldHeight-newHeight))];

                //adding subview
                [self addSubview:bView];
            }
            else
            {                
                double angle= [[self angleValueForBlockHeight:height] doubleValue];

                UIView *bView=[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[blocks objectAtIndex:blockCounter]]];
                [bView setFrame:CGRectMake(0.0, [y doubleValue], self.frame.size.width, blockSize.height)];
                [bView.layer setMasksToBounds:YES];

                [bView.layer setAnchorPoint:CGPointMake(0.5, 0.0)];
                [bView setFrame:CGRectMake(bView.frame.origin.x, bView.frame.origin.y-bView.frame.size.height/2.0, bView.frame.size.width, bView.frame.size.height)];

                if ([height doubleValue]!=blockSize.height)
                {
                    //preparing transform
                    CATransform3D basicTrans = CATransform3DIdentity;
                    basicTrans.m34 =1.0/-projection;

                    double rangle;
                    rangle=(360.0-angle)/360*(2.0*M_PI);

                    bView.layer.transform = CATransform3DRotate(basicTrans, rangle, 1.0f, 0.0f, 0.0f);

                };

                //adding subview
                [self addSubview:bView];
            };
        }
        else
        {
            //do not need to draw blocks with very low height
        };
    };
}

这是平移手势识别器代码:

-(void)handlePanGesture:(UIPanGestureRecognizer *)sender
{        
    double translatedY = [sender translationInView:self].y;
    double delta;

    if (fabs(translatedY)<fabs(oldTranslatedY))
    {
        [sender setTranslation:CGPointZero inView:self];
        oldTranslatedY=0.0;
        delta=0.0;
    }
    else
    {
        delta=translatedY-oldTranslatedY;
        oldTranslatedY=translatedY;
    };

    double pOffset=delta/((blockQuantity*blockSize.height)-self.frame.size.height);

    self.scrollPosition=self.scrollPosition-pOffset;

    if (self.scrollPosition<0.0)
    {
        self.scrollPosition=0.0;
    }
    else if(self.scrollPosition>1.0)
    {
        self.scrollPosition=1.0;
    };

    [self setNeedsLayout];
}

请随时问我任何问题。

更新:将代码从drawRect:方法移动到layoutSubviews

您可以使用Instruments来检查哪种方法花费最多的时间,但是我认为它正在取消存档和创建UIView。 你为什么需要它? 如果您每次都需要UIView,为什么不将其保存在内存中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM