我看到很多线程与这个问题有关,但没有一个解决我的问题(我认为).
我的情况应该很简单,我的控制器中有一个自定义UIView,从我的控制器,我使用[self.myView setNeedsDisplay],它完美地工作.
当我试图从UIView本身内部调用它时,我遇到了问题…我从另一个类发送了一个通知,我的View(这个工作)收到了它通过的信息,我更新了这个视图的内部属性,而不是我调用[self setNeedsDisplay]希望我的屏幕更新为新状态,但没有发生任何事情,我在drawRec方法中使用了一个NSLOG,此时它没有被调用,它只在我的控制器类调用setNeedsDisplay时调用,当发生这种情况时,之前应该发生的更新显示在屏幕上……我不知道为什么它之前没有更新…
这是一些代码:
我的控制器要求更新:(工作正常!)
- (void)addNodeToNetwork:(DTINode *)node { [self.myNetwork addNodeInTheNetwork:node]; self.gridView.nodesToDraw = [self.myNetwork.nodesInNetwork copy]; CGRect tempRec = CGRectMake(node.nodePosition.x,node.nodePosition.y node.nodePosition.x,node.nodePosition.y); NSValue *rectObj = [NSValue valueWithCGRect:tempRec]; //transforma o cgrect num objeto [self.gridView.fatherNodes setValue:rectObj forKey:node.nodeName]; [self.gridView setNeedsDisplay]; }
- (void) receiveTestNotification:(NSNotification *) notification { NSDictionary *userInfo = notification.userInfo; DTINode *notificationNode = [userInfo objectForKey:@"myNode"]; NSLog(@"Im Here!"); for (DTINode *node in self.nodesToDraw) { NSLog(@"Here too"); if(node.nodeName == notificationNode.fatherNode) { CGRect temp = CGRectMake(notificationNode.nodePosition.x,notificationNode.nodePosition.y,node.nodePosition.x,node.nodePosition.y); NSValue *tempObj = [NSValue valueWithCGRect:temp]; [self.fatherNodes setObject:tempObj forKey:notificationNode.nodeName]; [self setNeedsDisplay]; NSLog(@"Should REDRAW NOW!"); // It print this but no drawing is made! } } }
我没有粘贴我的drawRect,因为它有效,问题是没有从我的UIView setNeedsDisplay内部调用!
任何人都知道为什么这不起作用????
解决方法
经过大量的测试后,我看到了一些与线程有关的东西,事实上setNeedsDisplay只能在mainThread中调用…除了我从未在这个类中启动过separeted线程之外,引发Notification的类是在一个辅助线程中……并且显然这导致了这个问题……
解决它我只是强制在主线程中调用setNeedsDisplay ..
dispatch_async(dispatch_get_main_queue(),^{ [self setNeedsDisplay]; });
斯威夫特3:
DispatchQueue.main.async { [weak self] in self?.setNeedsDisplay() }