- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用绘图应用程序,我使用 CGlayers 进行绘图。触摸结束时,我从图层中获取图像并将其存储在数组中,我用它来撤消操作。
我的触摸结束功能
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches ended");
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawLayerInRect(context, self.bounds, self.drawingLayer);
m_curImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[m_undoArray addObject: m_curImage];
}
我的绘图 View 根据用户需求动态扩展,因此假设用户可以绘制一条drawView大小为200*200的线,然后将其扩展至200*300并再绘制一条线,然后将其扩展至200*300并绘制还有一行。
这是应用程序的图像
现在我在 UndoArray 中有 3 个不同大小的图像。
每当我增加/减少 Canvas 大小时。我写了这段代码
关于drawingView的增加和减少,我正在编写这个函数
(void)increaseDecreaseDrawingView
{
self.currentDrawingLayer = nil;
if(self.permanentDrawingLayer)
{
rectSize = self.bounds;
NSLog(@"Size%@", NSStringFromCGRect(self.bounds));
CGContextRef context = UIGraphicsGetCurrentContext();
//self.newDrawingLayer = CGLayerCreateWithContext(context, self.bounds.size, NULL);
CGFloat scale = self.contentScaleFactor;
CGRect bounds = CGRectMake(0, 0, self.bounds.size.width * scale, self.bounds.size.height * scale);
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
CGContextRef layerContext = CGLayerGetContext(layer);
CGContextScaleCTM(layerContext, scale, scale);
self.newDrawingLayer = layer;
CGContextDrawLayerInRect(layerContext, self.bounds, self.permanentDrawingLayer );
self.permanentDrawingLayer = nil;
}
为了进行撤消,我编写了这段代码
- (void)Undo
{
//Destroy the layer and create it once again with the image you get from undoArray.
self.currentDrawingLayer = Nil;
CGContextRef layerContext1 = CGLayerGetContext(self.permanentDrawingLayer );
CGContextClearRect(layerContext1, self.bounds);
CGContextRef context = UIGraphicsGetCurrentContext();
for(int i =0; i<[m_rectArrayUndo count];i++)
{
CGRect rect = [[m_rectArrayUndo objectAtIndex:i]CGRectValue];
CGLayerRef undoLayer = CGLayerCreateWithContext(context, rect.size, NULL);
CGContextRef layerContext = CGLayerGetContext(undoLayer );
CGContextTranslateCTM(layerContext, 0.0, rect.size.height);
CGContextScaleCTM(layerContext, 1.0, -1.0);
CGRect imageFrame;
NSDictionary *lineInfo = [m_undoArray objectAtIndex:i];
m_curImage = [lineInfo valueForKey:@"IMAGE"];
imageFrame = CGRectMake(0 ,0,m_curImage.size.width,m_curImage.size.height);
CGContextDrawImage(layerContext, imageFrame, m_curImage.CGImage);
CGContextDrawLayerInRect(context, rect, undoLayer );
CGContextDrawLayerInRect(layerContext1, rect, undoLayer);
}
}
在我的drawRect函数中,我编写了这段代码
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();//Get a reference to current context(The context to draw)
if(self.currentDrawingLayer == nil)
{
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
self.currentDrawingLayer = layer;
}
if(self.permanentDrawingLayer == nil)
{
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
self.permanentDrawingLayer = layer;
}
if(self.newDrawingLayer == nil)
{
CGLayerRef layer = CGLayerCreateWithContext(context, bounds.size, NULL);
self.newDrawingLayer = layer;
}
CGPoint mid1 = midPoint(m_previousPoint1, m_previousPoint2);
CGPoint mid2 = midPoint(m_currentPoint, m_previousPoint1);
CGContextRef layerContext = CGLayerGetContext(self.currentDrawingLayer);
CGContextSetLineCap(layerContext, kCGLineCapRound);
CGContextSetBlendMode(layerContext, kCGBlendModeNormal);
CGContextSetLineJoin(layerContext, kCGLineJoinRound);
CGContextSetLineWidth(layerContext, self.lineWidth);
CGContextSetStrokeColorWithColor(layerContext, self.lineColor.CGColor);
CGContextSetShouldAntialias(layerContext, YES);
CGContextSetAllowsAntialiasing(layerContext, YES);
CGContextSetAlpha(layerContext, self.lineAlpha);
CGContextSetFlatness(layerContext, 1.0f);
CGContextBeginPath(layerContext);
CGContextMoveToPoint(layerContext, mid1.x, mid1.y);//Position the current point
CGContextAddQuadCurveToPoint(layerContext, m_previousPoint1.x, m_previousPoint1.y, mid2.x, mid2.y);
CGContextStrokePath(layerContext);//paints(fills) the line along the current path.
CGContextDrawLayerInRect(context, self.bounds, self.newDrawingLayer);
CGContextDrawLayerInRect(context, self.bounds, self.permanentDrawingLayer);
CGContextDrawLayerInRect(context, self.bounds, self.currentDrawingLayer);
[super drawRect:rect];
}
我没有什么疑问
这是正确的方法吗?或者他们有更好的方法吗?
这里发生的情况是,我的撤消数组中的图像不尊重矩形,而是在新图层上的任意随机位置绘制。
所以我想知道如何正确绘制它们,以便在 CGlayer 上的特定位置正确绘制图像。
最佳答案
首先,由于您正在使用图层,我建议放弃 drawRect:
并仅使用 CALayer
变换。
其次,在我看来,实现撤消重做操作的最佳方式始终是基于命令的。作为一个非常简单的示例,您可以为每个命令创建单独的方法:
- (void)scaleLayerBy:(CGFloat)scale;
- (void)moveLayerByX:(CGFloat)x Y:(CGFloat)y;
// etc
然后每次用户执行操作时,您都将操作 ID 和参数添加到 NSMutableArray
中:
[self.actionHistory addObject:@{ @"action": @"move", @"args": @[@10.0f, @20.0f] }];
相反,如果用户调用撤消,则删除该数组中的最后一个对象。
然后,当您需要重新加载显示时,只需重新评估数组中的所有命令即可。
[self resetLayers]; // reset CALayers to their initial state
for (NSDictionary *command in self.actionHistory) {
NSArray *arguments = command[@"args"];
if ([command[@"action"] isEqualToString:@"move"]) {
[self moveLayerByX:[arguments[0] floatValue] Y:[arguments[1] floatValue]];
}
// else if other commands
}
关于ios - 使用 Cglayer 绘图进行撤消和重做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21027788/
我有一个关于 JavaScript 语法的问题。实际上,我在自学 MEAN 堆栈教程时想出了编码(https://thinkster.io/mean-stack-tutorial#adding-aut
在我的书中它使用了这样的东西: for($ARGV[0]) { Expression && do { print "..."; last; }; ... } for 循环不完整吗?另外,do 的意义何
我已经编写了读取开关状态的代码,如果按 3 次 # 则退出。 void allkeypadTest(void) { static uint8_t modeKeyCount=0; do
因此,对于上周我必须做的作业,我必须使用 4 个 do-while 循环和 if 语句在 Java 中制作一个猜谜游戏。我无法成功完成它,类(class)已经继续,没有为我提供任何帮助。如果有人可以查
int i=1,j=0,n=10,k; do{ j+=i; i<<1; printf("%d\n",i); // printf("%d\n",12<<1); }while
此代码用于基本杂货计算器的按钮。当我按下按钮时,一个输入对话框会显示您输入商品价格的位置。我遇到的问题是我无法弄清楚如何获得 do ... while 循环以使输入对话框在输入后弹出。 我希望它始终恢
当我在循环中修改字符串或另一个变量时,它的条件是否每次都重新计算?或者在循环开始前一次 std::string a("aa"); do { a = "aaaa"; } while(a.size<10)
我刚刚写了这个,但我找不到问题。我使用代码块并编写了这个问题 error: expected 'while' before '{' token === Build finished: 1 errors
do { printf("Enter number (0-6): ", ""); scanf("%d", &Num); }while(Num >= 0 && Num 表示“超过”,<表
我有一个包含 10 个项目的 vector (为简单起见,所有项目都属于同一类,称其为“a”)。我想要做的是检查“A”不是 a) 隐藏墙壁或 b) 隐藏另一个“A”。我有一个碰撞函数可以做到这一点。
嗨,这是我的第二个问题。我有下表 |-----|-------|------|------| |._id.|..INFO.|.DONE.|.LAST.| |..1..|...A...|...N..|.
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicates: Why are there sometimes meaningless do/while and if/e
来自 wikibook在 F# 上有一小部分它说: What does let! do?# let! runs an async object on its own thread, then it i
我在 Real World Haskell 书中遇到了以下函数: namesMatching pat | not (isPattern pat) = do exists do
我有一个类似于下面的用例,我创建了多个图并使用 gridExtra 将它们排列到一些页面布局中,最后使用 ggsave 将其保存为 PDF : p1 % mutate(label2
当我使用具有 for 循环的嵌套 let 语句时,如果没有 (do (html5 ..)),我将无法运行内部 [:tr]。 (defpartial column-settings-layout [&
执行 vagrant up 时出现此错误: anr@anr-Lenovo-G505s ~ $ vagrant up Bringing machine 'default' up with 'virtua
# ################################################# # Subroutine to add data to the table Blas
我想创建一个检查特定日期格式的读取主机。此外,目标是检查用户输入是否正确,如果不正确,则提示应再次弹出。 当我刚接触编程时,发现了这段代码,这似乎很合适。我仍然在努力“直到” do {
我关注这个tutorial在谷歌云机器学习引擎上进行培训。我一步一步地跟着它,但是在将 ml 作业提交到云时我遇到了错误。我运行了这个命令。 sam@sam-VirtualBox:~/models/r
我是一名优秀的程序员,十分优秀!