SetNeedsDisplay not working

Plauto Abreu picture Plauto Abreu · Dec 17, 2012 · Viewed 12.6k times · Source

I saw many threads related to this issue, but none addresses my case (I think).

My case should be simple, I have a Custom UIView in my controller, from my controller, I use the [self.myView setNeedsDisplay] and it works perfectly.

I'm having problems when Im trying to call this from inside of the UIView itself...I have a notification being sent from another class, and it is being received by my View (this works) with the information it passes, I update internal properties of this view and than I'm calling the [self setNeedsDisplay] wishing to have my screen updated with the new states, but nothing is happening, I used a NSLOG inside my drawRec method, and it is not being called at this time, it is only called when my controller class call the setNeedsDisplay, and when that happens, the update that should have happened before is showed on screen... I don't know why its not updating before...

Here are some code:

My controller asking for update: (works OK!)

- (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];
}

My notification method trying to update my drawing: (Not Working ! )

- (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!
    }
}
}

I'm not pasting my drawRect here because it works, the problem is that is is not being called from inside my UIView setNeedsDisplay!

Anyone have any idea why this is not working????

Answer

Plauto Abreu picture Plauto Abreu · Dec 20, 2012

After alot of testing, I saw something related to threads and the fact setNeedsDisplay should only be called in the mainThread...besides I never started a separeted thread in this classes, the class that raised the Notification was in a secondary thread...and aparently this was causing the issue...

to Solve it I just forced setNeedsDisplay to be called in the main thread..

dispatch_async(dispatch_get_main_queue(), ^{
            [self setNeedsDisplay];  
});

Swift 3:

DispatchQueue.main.async { [weak self] in
    self?.setNeedsDisplay()
}