标签: drawrect

运行循环/ drawRect中的神秘"渐进式减速"问题

这是一个真正的谜.

想象一下,您正在进行在屏幕外绘制复杂图像的传统过程(CGLayer),并且您在绘制时间歇性地将图像更新到屏幕上.

如您所知,执行此操作的方法是:在后台运行大型绘图过程,并根据需要调用setNeedsDisplays的前景,从而更新图像.这是微不足道的,可以通过两行代码实现.

但是,当你这样做时,会出现一个神秘的问题:每个绘图周期所花费的时间,每次都会增加,变得无法使用.此外,时间可能不规律地变化.

这是一个已知的iOS错误,还是?谁看过这个吗?

这是一个非常简单,非常容易理解的应用程序,可以解决问题:

http://www.fileswap.com/dl/p8lU3gAi/stepwiseDrawingV2.zip.html

输出示例如下.

有谁知道为什么会这样?操作系统的行为非常奇怪.

后来 ...... FELZ已经找到了令人震惊的解决方案.Felz副本的CGLayer一次每一轮.这完全阻止了这种奇怪的行为.

然而,对于究竟发生了什么仍然没有真正清楚的理解:因此从字面上看,当奇怪的问题出现时,时间在哪里?

这是一个很长的输出示例......

请注意,您有时会得到一个"双重奇异"的结果,如下所示:它表现出"正常"奇怪的行为:每次都会增加时间.然而,偶尔会有几轮时间"非常快",然后返回.怪啊?此外,如果您在模拟器上运行,请快速单击Mac上不相关的应用程序,以获得"更奇怪"的结果.

尽管费尔兹给出了一个完美的工作答案,但实际的机制仍然是一个谜.

:26:56.697 stepwiseDrawing[5334:1a03] time difference was     0
:26:56.707 stepwiseDrawing[5334:1a03] time difference was    10
:26:56.717 stepwiseDrawing[5334:1a03] time difference was    10
:26:56.744 stepwiseDrawing[5334:1a03] time difference was    27
:26:56.771 stepwiseDrawing[5334:1a03] time difference was    27
:26:56.807 stepwiseDrawing[5334:1a03] time difference was    37
:26:56.829 stepwiseDrawing[5334:1a03] time difference was    22
:26:56.864 stepwiseDrawing[5334:1a03] time difference was    35
:26:56.891 stepwiseDrawing[5334:1a03] time difference was    28
:26:56.936 stepwiseDrawing[5334:1a03] time difference was    45 …
Run Code Online (Sandbox Code Playgroud)

iphone cocoa drawrect ios

7
推荐指数
1
解决办法
1944
查看次数

UIView重写drawRect会导致视图不遵守masksToBounds

我试图drawRect:在我的自定义视图中覆盖UIView 的方法.但是,我的视图的边界半径定义为:

    sub = [[[NSBundle mainBundle] loadNibNamed:@"ProfileView" owner:self options:nil] objectAtIndex:0];
    [self addSubview:sub];
    [sub setUserInteractionEnabled:YES];
    [self setUserInteractionEnabled:YES];
    CALayer *layer = sub.layer;
    layer.masksToBounds = YES;
    layer.borderWidth = 5.0;
    layer.borderColor = [UIColor whiteColor].CGColor;
    layer.cornerRadius = 30.0;
Run Code Online (Sandbox Code Playgroud)

这完美地工作,并在我的视图周围放置一个边框半径很好的边框(不要介意背面的对角线/直线白线,它们与此视图无关):

纠正一个

但是,当我尝试drawRect:在我的视图中覆盖该方法时,我可以看到黑色背景没有掩盖到边界.我没有做任何事情(目前),这里是我的代码:

-(void)drawRect:(CGRect)rect{
    [super drawRect:rect];
}
Run Code Online (Sandbox Code Playgroud)

这是结果:

不正确的

我只改变了绘制方法.如何在保持视图遵循角半径蒙版的同时覆盖绘制方法?这是iOS中的错误还是我错过了什么?

uiview drawrect ios ios6

7
推荐指数
1
解决办法
3844
查看次数

为什么自定义drawRect未在6.1模拟器中显示?

里面有一个UIView子类(ThumbView)UICollectionViewCell.以下代码在iOS 7模拟器中运行良好:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identifier = @"Cell";
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
    ThumbView *thumbView = (ThumbView *)[cell viewWithTag:1];
    [thumbView setNeedsDisplay];
    return cell;
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是,在iOS 6版本的模拟器中:

网格都消失了:

在此输入图像描述

我已经把NSLogdrawRect该ThumbView,以确保drawRect被调用.

怎么了?

  • Xcode 5.0版(5A1412)
  • iOS模拟器7.0版(463.9.4)

更新(图纸代码):

- (void)drawRect:(CGRect)rect
{
    NSLog(@"%s", __func__);
   [self drawGrid:rect];
}

- (void)drawGrid:(CGRect)rect
{
    CGFloat margin = self.margin;
    CGFloat lineWidth = 2.0;

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGRect gridRect = CGRectInset(rect, margin, margin);

    for …
Run Code Online (Sandbox Code Playgroud)

drawrect ios ios-simulator

7
推荐指数
1
解决办法
251
查看次数

子类UITableViewCell - backgroundView掩盖了我在drawRect中所做的任何事情

我正在尝试创建一个子类UITableViewCell,我在右上角绘制一个图像.我有完美的工作 - 除非我设置self.backgroundView,我的背景图像掩盖了drawRect中绘制的图像.

必须有一种方法可以设置背景图像(和selectedBackgroundView),而不会掩盖drawRect中正在进行的操作.

我是以错误的方式来做这件事的吗?

编辑:我已经发布了一个问题示例项目.

    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {

    if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) {

     // TODO: figure out why this covers up self.starImage that's drawn in drawRect
         self.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellBackground.png"]] autorelease];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    [self.starImage drawAtPoint:CGPointMake(self.bounds.size.width - self.starImage.size.width, 0.0)];
}
Run Code Online (Sandbox Code Playgroud)

编辑2:在AWrightIV的要求下,这是我如何工作...这根本不需要子类化UITableViewCell.我只是在cell.backgroundView中添加一个子视图:

// create a UIImageView that contains the background image for the cell
UIImageView *bgImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"cellBackground.png"]];

// create another UIImageView that contains the …
Run Code Online (Sandbox Code Playgroud)

iphone uitableview drawrect

6
推荐指数
1
解决办法
1万
查看次数

iOS CGPath性能

UPDATE

通过使用OpenGL绘制所有内容,我克服了CG的局限性.还是有一些小故障,但到目前为止它工作得更快,更快.

一些有趣的观点:

  • GLKView:这是一个特定于iOS的视图,它在设置OpenGL上下文和渲染循环方面有很大帮助.如果你不在iOS上,我担心你是独自一人.
  • 着色器精度:当前版本的OpenGL ES(2.0)中着色器变量的精度为16位.这对我来说有点低,所以我模拟了32位算术,其中包含16位变量对.
  • GL_LINES:OpenGL ES可以原生地绘制简单的线条.不是很好(没有关节,没有帽子,请看下面屏幕截图顶部的紫色/灰色线条),但为了改善你必须编写一个自定义着色器,将每一行转换成三角形条并祈祷它作品!(据说当浏览器告诉你Canvas2D是GPU加速时,浏览器会这样做)

                                                      示例渲染

  • 画得尽可能少.我认为这是有道理的,但你可以经常避免渲染事物,例如,在视口之外.
  • OpenGL ES 支持填充多边形,因此您必须自己进行测试.考虑使用iPhone-GLU:这是MESA代码的一个端口,它非常好,虽然它有点难以使用(没有标准的Objective-C接口).

原始问题

我正在尝试在drawRect滚动视图的方法中绘制大量CGPath(通常超过1000),当用户用手指平移时刷新.我在浏览器的JavaScript中使用相同的应用程序,我正在尝试将其移植到iOS本机应用程序.

iOS测试代码是(100行操作,path是预先制作的CGMutablePathRef):

- (void) drawRect:(CGRect)rect {
    // Start the timer
    BSInitClass(@"Renderer");
    BSStartTimedOp(@"Rendering");

    // Get the context
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 2.0);
    CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
    CGContextSetStrokeColorWithColor(context, [[UIColor blueColor] CGColor]);
    CGContextTranslateCTM(context, 800, 800);

    // Draw the points
    CGContextAddPath(context, path);
    CGContextStrokePath(context);

    // Display the elapsed time
    BSEndTimedOp(@"Rendering"); …
Run Code Online (Sandbox Code Playgroud)

drawing drawrect ios

6
推荐指数
1
解决办法
2066
查看次数

UIView绘制最佳实践

我的应用程序能够做一些简单的图形绘制(直到我得到一个更稳定的代码,我只坚持一个图),它也能够重新调整它们的大小.我用来创建a的代码UIView如下:

- (void)drawRect:(CGRect)rect
{    
    CGContextRef context = UIGraphicsGetCurrentContext();

    [self setContextFillColor:context];
    [self setContextStrokeColor:context];
    [self setLineWidth:context];

    CGFloat lineThickness = [self lineWidth] ;
    CGFloat halfLineThickess = lineThickness / 2.0f;

    CGContextAddRect(context, CGRectMake(halfLineThickess,halfLineThickess, rect.size.width - lineThickness, rect.size.height - lineThickness));

    CGContextDrawPath(context, kCGPathEOFillStroke);
}
Run Code Online (Sandbox Code Playgroud)

这给了我,输入大小为(100.0f,100.0f),这个:

在此输入图像描述

这个数字在一个"容器" UIView里面,而"容器" 又在里面UIScrollView.我的问题是当我重新调整我的身材并且我达到大约1000*1000的大小(我的"容器"是20,000*20,000)时,我开始接收内存警告并且应用程序最终放弃了.所以我的问题是:

1)我应该考虑为此设置最大尺寸UIView吗?

2)我怎样才能使用仪器来跟踪这类问题,看看问题出在哪里(或者在哪里进行繁重的工作).

3)我应该使用某种像缓存这样

4)在绘制时,是否有一些一般的最佳实践需要考虑UIView

5)我应该考虑一下CALayer,虽然我需要听一听吗?

重新调整大小UIView主要基于.

objective-c uiview drawrect ios

6
推荐指数
1
解决办法
1072
查看次数

iOS,绘制填充recrangle的径向渐变

下面的代码绘制了一个完美的椭圆径向渐变,但没有填充它的视角.如何让它超出椭圆的边缘?记录的选项是kCGGradientDrawsAfterEndLocation,但我认为它在ios中不可用.

- (void)drawRect:(CGRect)rect
{
    CGFloat colors [] = {
        0.2, 0.2, 0.2, 1.0,
        0.0, 0.0, 0.0, 1.0
    };
    CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, colors, NULL, 2);
    CGColorSpaceRelease(baseSpace), baseSpace = NULL;
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextAddEllipseInRect(context, rect);
    CGContextClip(context);
    CGContextDrawRadialGradient(context, gradient, self.center, 0, self.center, self.frame.size.width, kCGGradientDrawsAfterEndLocation);
    CGGradientRelease(gradient), gradient = NULL;
    CGContextRestoreGState(context);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

gradient uiview drawrect ios

6
推荐指数
1
解决办法
3459
查看次数

检查NSRutton是否在drawRect上关闭

我想在我的自定义drawRect方法中检查我的自定义NSButton当前是否处于按下状态(用户正在点击它).像这样的东西:

- (void)drawRect:(NSRect)dirtyRect{
    if ([self buttonIsInPressedState]) {
        [[self alternateBGImage] drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
    }else{
        [[self BGImage] drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
    }
    [super drawRect:dirtyRect];
}
Run Code Online (Sandbox Code Playgroud)

你会怎么检查这样的事情?可能吗?

我最终检查了按钮单元格上的mouseDownFlags.不知道这是否是"正确"的方式,所以如果你有更好的建议,请告诉我:

- (void)drawRect:(NSRect)dirtyRect{        
    if ([self.cell mouseDownFlags] == 0) {
        [[self BGImage] drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
    }else{
        [[self alternateBGImage] drawInRect:dirtyRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0f];
    }

    [super drawRect:dirtyRect];
}
Run Code Online (Sandbox Code Playgroud)

macos xcode objective-c drawrect nsbutton

6
推荐指数
2
解决办法
2084
查看次数

setNeedsDisplay不触发DrawRect

我有一个viewController,它显然是UIViewController被调用的子类MapViewController.在这个viewController中,我使用GPS来获取用户的位置.

我也有一个叫做的观点DrawCircle.该视图是其子类UIView.

使用drawCircle我希望能够随时在我的MapViewController上绘图.但我不确定我是否理解这样做的概念.我知道我的绘图代码正在运行,我之前使用过它.但我不知道如何MapViewController使用DrawCircle.

从我看来,只要我打电话[myCustomView setNeedsDisplay],它就不会DrawRect在我看来调用方法.

这是一些代码: MapViewController.h

#import "DrawCircle.h"


@interface MapViewController: UIViewController <CLLocationManagerDelegate>{
    DrawCircle *circleView;
}

@property (nonatomic, retain) DrawCircle *circleView;
@end
Run Code Online (Sandbox Code Playgroud)

MapViewController.m

#import "DrawCircle.h"

@interface MapViewController ()
@end

@implementation MapViewController
@synthesize circleView;

- (void) viewDidLoad
{
    circleView = [[DrawCircle alloc] init];
    [self setNeedsDisplay];

    [super viewDidLoad];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end
Run Code Online (Sandbox Code Playgroud)

DrawCircle.m

#import "DrawCircle.h"

@interface DrawCircle() 
@end

@implementation DrawCircle

-(id)initWithFrame:(CGRect)frame { …
Run Code Online (Sandbox Code Playgroud)

objective-c drawrect ios

6
推荐指数
1
解决办法
8115
查看次数

使用带有蒙版图像的圆形进度条?

我正在制作一个循环进度条,用于自定义游戏中心成就视图,我有点"碰壁".我正在为此奋斗超过两个小时仍然无法让它工作.

问题是,我需要一个循环进度条,在那里我可以设置(至少)轨道(填充)图像.因为我的进度填充是渐变的彩虹,我不能仅使用代码获得相同的结果.

我正在搞乱CALayers和drawRect方法,但是我没有成功.你能给我一点指导吗?

以下是循环进度条的示例:https : //github.com/donnellyk/KDGoalBar https://github.com/danielamitay/DACircularProgress

我只需要填充是一个蒙面图像,取决于进度.如果你甚至可以让它的工作进展动画,那真的很酷,但我不需要帮助:)

谢谢,尼克

core-graphics objective-c calayer drawrect

6
推荐指数
1
解决办法
6782
查看次数