Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c Xcode(Obj-C)在用户已经可以看到窗口后更新UIView(NSRect)_Objective C_Xcode_Uikit - Fatal编程技术网

Objective c Xcode(Obj-C)在用户已经可以看到窗口后更新UIView(NSRect)

Objective c Xcode(Obj-C)在用户已经可以看到窗口后更新UIView(NSRect),objective-c,xcode,uikit,Objective C,Xcode,Uikit,我对使用Objective-C创建Xcode项目相当陌生,我正在尝试制作一个简单的2d图形程序,在我在其他地方实现之前,向我展示我的图形代码的工作情况 我把所有的东西都画好了,但当我想清除笔划和画新线时,问题就来了。从我运行程序时看到的情况来看,视图只会在实现结束时点击@end时显示我执行的内容。问题是,当它到达@end时,代码已经运行了。我不知道是否需要在循环中调用类来每次更新视图(或者在何处或如何进行更新,可能是main.m中的某个内容),或者是否需要在视图退出实现之前调用函数来更新视图,因

我对使用Objective-C创建Xcode项目相当陌生,我正在尝试制作一个简单的2d图形程序,在我在其他地方实现之前,向我展示我的图形代码的工作情况

我把所有的东西都画好了,但当我想清除笔划和画新线时,问题就来了。从我运行程序时看到的情况来看,视图只会在实现结束时点击@end时显示我执行的内容。问题是,当它到达@end时,代码已经运行了。我不知道是否需要在循环中调用类来每次更新视图(或者在何处或如何进行更新,可能是main.m中的某个内容),或者是否需要在视图退出实现之前调用函数来更新视图,因为现在所有行都只是在用户看到任何内容之前相互覆盖

以下是我的头文件中的接口(连接到UIView):

实施文件:

以下是我创建矩形的方式:

- (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:
    消息,在视图第一次出现时绘制视图

  • 如果要更改视图,请使视图的一部分无效(即
    view.needsDisplay=YES
    )。那你就等着吧。很快,Cocoa将再次发送
    -drawRect:
    ,您的类将绘制新的和改进的图像,并显示在屏幕上

  • 许多更改都会导致视图无效,并随后自动重新绘制,例如,如果调整了视图的大小。但是,除非您做出Cocoa知道需要视图重新绘制自身的更改,否则您必须自己使视图无效

现在,对于挑剔,我希望您理解这一切都是为了帮助您理解正在发生的事情并改进您的代码

  • 你的主题行写的是
    UIView
    ,但你的代码示例子类是
    NSView
    ,所以我不确定你是在写macOS还是iOS应用程序。这没什么大不了的,因为在这个层次上,差异是最小的

  • 您的
    -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];