【问题标题】:Objective C - Sketch Application will not draw long linesObjective C - Sketch 应用程序不会画长线
【发布时间】:2015-07-08 21:04:14
【问题描述】:

我有一个 iPhone 应用程序,我在其中提供了一个草图板供用户保存签名。 UIImageView 被添加到主视图并保存笔画。出于某种原因,您只能在焊盘上绘制短线,如下图所示。

我有另一个使用相同代码的 iPad 应用程序,它运行良好。我不确定是什么原因造成的。我没有使用任何会干扰它的触摸或手势代码。以下是我使用的一些代码。

更新:如果我创建一个具有相同类的 UIViewController 并使其成为根视图控制器,那么它可以正常工作。我的导航层次结构中的某些东西正在做一些奇怪的事情。

-(void)SetUpSignaturePad{
//create a frame for our signature capture
imageFrame = CGRectMake(self.view.frame.origin.x,
                        self.view.frame.origin.y,
                        self.view.frame.size.width + 23,
                        self.view.frame.size.height + 7 );
//allocate an image view and add to the main view
    mySignatureImage = [[UIImageView alloc] initWithImage:nil];
    mySignatureImage.frame = imageFrame;
    mySignatureImage.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:mySignatureImage];
}

//when one or more fingers touch down in a view or window
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

//did our finger moved yet?
fingerMoved = NO;
UITouch *touch = [touches anyObject];

//we need 3 points of contact to make our signature smooth using quadratic bezier curve
currentPoint = [touch locationInView:mySignatureImage];
lastContactPoint1 = [touch previousLocationInView:mySignatureImage];
lastContactPoint2 = [touch previousLocationInView:mySignatureImage];


//when one or more fingers associated with an event move within a view or window
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

//well its obvious that our finger moved on the screen
fingerMoved = YES;
UITouch *touch = [touches anyObject];

//save previous contact locations
lastContactPoint2 = lastContactPoint1;
lastContactPoint1 = [touch previousLocationInView:mySignatureImage];
//save current location
currentPoint = [touch locationInView:mySignatureImage];

//find mid points to be used for quadratic bezier curve
CGPoint midPoint1 = [self midPoint:lastContactPoint1 withPoint:lastContactPoint2];
CGPoint midPoint2 = [self midPoint:currentPoint withPoint:lastContactPoint1];

//create a bitmap-based graphics context and makes it the current context
UIGraphicsBeginImageContext(imageFrame.size);

//draw the entire image in the specified rectangle frame
[mySignatureImage.image drawInRect:CGRectMake(0, 0, imageFrame.size.width, imageFrame.size.height)];

//set line cap, width, stroke color and begin path
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 3.0f);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);
CGContextBeginPath(UIGraphicsGetCurrentContext());

//begin a new new subpath at this point
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), midPoint1.x, midPoint1.y);
//create quadratic Bézier curve from the current point using a control point and an end point
CGContextAddQuadCurveToPoint(UIGraphicsGetCurrentContext(),
                             lastContactPoint1.x, lastContactPoint1.y, midPoint2.x, midPoint2.y);

//set the miter limit for the joins of connected lines in a graphics context
CGContextSetMiterLimit(UIGraphicsGetCurrentContext(), 2.0);

//paint a line along the current path
CGContextStrokePath(UIGraphicsGetCurrentContext());

//set the image based on the contents of the current bitmap-based graphics context
mySignatureImage.image = UIGraphicsGetImageFromCurrentImageContext();

//remove the current bitmap-based graphics context from the top of the stack
UIGraphicsEndImageContext();

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
//if the finger never moved draw a point
if(!fingerMoved) {
    UIGraphicsBeginImageContext(imageFrame.size);
    [mySignatureImage.image drawInRect:CGRectMake(0, 0, imageFrame.size.width, imageFrame.size.height)];

    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), 3.0f);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 1.0);
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    CGContextFlush(UIGraphicsGetCurrentContext());

    mySignatureImage.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    }
}

//calculate midpoint between two points
- (CGPoint) midPoint:(CGPoint )p0 withPoint: (CGPoint) p1 {
    return (CGPoint) {
        (p0.x + p1.x) / 2.0,
        (p0.y + p1.y) / 2.0
    };
}

【问题讨论】:

    标签: ios objective-c uiimageview cgcontext


    【解决方案1】:

    很遗憾地告诉您,我没有真正的解决方案,但您的问题很可能是由于性能问题。为什么?因为每次检测到手势时您都在创建图像。创建图像需要耗费时间和资源的屏幕渲染。
    您应该将代码基于具有绘图功能的同一个项目,通常使用在 drawRect 方法中更新其绘图的视图,因为您也许 CAShapeLaywr 也可以。
    仪器中的 Run Time Profiler 和搜索方法正在缩短时间。

    【讨论】:

    • 我认为这不是性能问题。尝试绘制时,资源使用量几乎没有增加。
    猜你喜欢
    • 2015-09-21
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多