10

この問題に関連する多くのスレッドを見ましたが、私のケースに対処するものはありませんでした (私は思います)。

私の場合は単純なはずです。コントローラーにカスタムUIViewがあり、コントローラーから [ self.myView setNeedsDisplay] を使用すると、完全に機能します。

自分自身の内部からこれを呼び出そうとすると問題が発生しUIViewます...別のクラスから送信された通知があり、渡された情報とともにビュー(これは機能します)によって受信され、内部を更新しますこのビューのプロパティsetNeedsDisplayと、新しい状態で画面を更新したい[self ] を呼び出していますが、何も起こっていません。メソッドNSLOG内でa を使用しましたdrawRecが、現時点では呼び出されていません。私のコントローラークラスが を呼び出すときに呼び出され、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。問題は、 my の内部から呼び出されていないことUIView setNeedsDisplayです !

なぜこれが機能しないのか誰にも分かりますか????

4

2 に答える 2

28

多くのテストの後、スレッドに関連するものを見ました。setNeedsDisplay は mainThread でのみ呼び出す必要があるという事実を確認しました...このクラスで分離されたスレッドを開始したことがないことに加えて、通知を発生させたクラスはセカンダリスレッドにありました...明らかに、これが問題の原因でした...

それを解決するために、メインスレッドで setNeedsDisplay を強制的に呼び出すようにしました..

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

スウィフト 3:

DispatchQueue.main.async { [weak self] in
    self?.setNeedsDisplay()
}
于 2012-12-20T13:05:48.370 に答える
0

私はそれを使用する正しい方法は次のとおりだと思います:

[self setNeedsDisplay:YES]; 

私はいつもそれを機能させるのに問題がありますが:(

于 2013-01-07T05:44:38.030 に答える