Objective c Xcode(Obj-C)在用户已经可以看到窗口后更新UIView(NSRect)
我对使用Objective-C创建Xcode项目相当陌生,我正在尝试制作一个简单的2d图形程序,在我在其他地方实现之前,向我展示我的图形代码的工作情况 我把所有的东西都画好了,但当我想清除笔划和画新线时,问题就来了。从我运行程序时看到的情况来看,视图只会在实现结束时点击@end时显示我执行的内容。问题是,当它到达@end时,代码已经运行了。我不知道是否需要在循环中调用类来每次更新视图(或者在何处或如何进行更新,可能是main.m中的某个内容),或者是否需要在视图退出实现之前调用函数来更新视图,因为现在所有行都只是在用户看到任何内容之前相互覆盖 以下是我的头文件中的接口(连接到UIView): 实施文件: 以下是我创建矩形的方式:Objective c Xcode(Obj-C)在用户已经可以看到窗口后更新UIView(NSRect),objective-c,xcode,uikit,Objective C,Xcode,Uikit,我对使用Objective-C创建Xcode项目相当陌生,我正在尝试制作一个简单的2d图形程序,在我在其他地方实现之前,向我展示我的图形代码的工作情况 我把所有的东西都画好了,但当我想清除笔划和画新线时,问题就来了。从我运行程序时看到的情况来看,视图只会在实现结束时点击@end时显示我执行的内容。问题是,当它到达@end时,代码已经运行了。我不知道是否需要在循环中调用类来每次更新视图(或者在何处或如何进行更新,可能是main.m中的某个内容),或者是否需要在视图退出实现之前调用函数来更新视图,因
- (void)drawRect:(NSRect)dirtyRect {
[self clearGrid:dirtyRect];
[self drawLines];
}
- (void)clearGrid:(NSRect)theRect {
//Wiping the slate clean
[super drawRect:theRect];
[self.window setBackgroundColor:[NSColor whiteColor]];
...
下面是我用来画线的东西:
NSBezierPath* eqLine = [NSBezierPath bezierPath];
[[NSColor greenColor] setStroke];
[eqLine setLineWidth:5.0];
[eqLine moveToPoint:NSMakePoint([self convertToPixels:previousX], [self convertToPixels:previousY])];
[eqLine lineToPoint:NSMakePoint([self convertToPixels:finalX], [self convertToPixels:finalY])];
[eqLine stroke];
在过去的几天里,我一直在寻找如何解决这个问题,但到目前为止还没有找到任何答案,也许我只是没有找到正确的答案。任何信息都是有用的,即使它只是指向我可以查看的资源的一个点。如果需要任何其他信息,请告诉我。谢谢 很明显,你是这件事的绊脚石,这不是犯罪。所以这里有很多问题需要解决。让我们一次处理一件事 为了回答您的基本问题,每当视图需要绘制其图形表示时,都会调用
-drawRect:
方法。只要不会改变其图形表示形式,则只会收到一次-drawRect:
方法
若要通知Cocoa(或CoCoatTouch)图形表示已更改,请使视图的全部或部分无效。这可以通过多种方式实现,但最简单的方法是将needsDisplay
属性设置为YES
。一旦这样做,Cocoa将(在将来的某个时候)再次调用-drawRect:
方法来修改视图的图形表示。清洗,漂洗,重复
下面是基本流程:
- 创建类并将其添加到视图中。Cocoa通过发送class a
消息,在视图第一次出现时绘制视图-drawRect:
- 如果要更改视图,请使视图的一部分无效(即
)。那你就等着吧。很快,Cocoa将再次发送view.needsDisplay=YES
,您的类将绘制新的和改进的图像,并显示在屏幕上-drawRect:
- 许多更改都会导致视图无效,并随后自动重新绘制,例如,如果调整了视图的大小。但是,除非您做出Cocoa知道需要视图重新绘制自身的更改,否则您必须自己使视图无效
- 你的主题行写的是
,但你的代码示例子类是UIView
,所以我不确定你是在写macOS还是iOS应用程序。这没什么大不了的,因为在这个层次上,差异是最小的NSView
- 您的
调用-drawRect:
..,然后调用[self-clearGrid:
..时不要这样做。通常,除了从同名的重载方法中使用[super-drawRect:
之外,永远不要使用-drawRect:
。换句话说,super
可以使用-drawRect:
,但其他方法都不应该这样做。这并不“非法”,但从长远来看,它会让你免于悲伤[super drawRect:
- 您的
方法设置窗口的-clearGrid:
。不要这样做。窗口的背景色是一个属性,您的backgroundColor
方法应该只绘制视图的图形表示-drawRect:
- 您正在从
(或NSView
)的直接子类中调用UIView
)。这没关系,但没有必要。这两个基类都清楚地记录了它们的[super-drawRect:
方法不起任何作用,因此调用它没有任何好处。同样,它不会造成任何伤害,只是毫无意义。当-drawRect:
方法开始执行时,图形上下文已经被设置、清除,准备好了,开始画画吧-drawRect:
不是一个语句。它不会被“执行”。它只是一个单词,告诉编译器类的源代码已经结束。执行的是方法,如@end
-drawRect:
- 在
部分中,您声明了@interface
方法。这是多余的,因为-drawRect:
方法已在超类中声明-drawRect:
NSView
的窗口直到-drawRect:
方法结束后才打开,所以我所做的就是更新用户还看不到的窗口中的视图t point是打开的窗口,在-drawRect:
结束之前,我有没有办法手动打开它?另外,我真的很感谢您非常详细的回答,正是像您这样的人帮助互联网变得更好。通常,您从不担心drawRect:
什么时候被调用。Cocoa会计算出何时、是否会被调用有可能是
NSBezierPath* eqLine = [NSBezierPath bezierPath];
[[NSColor greenColor] setStroke];
[eqLine setLineWidth:5.0];
[eqLine moveToPoint:NSMakePoint([self convertToPixels:previousX], [self convertToPixels:previousY])];
[eqLine lineToPoint:NSMakePoint([self convertToPixels:finalX], [self convertToPixels:finalY])];
[eqLine stroke];