Question

My app has two different states, and every state will be representing with a NSView.

so there is only one view showed at a time, the problem is when I switched between the views the app doesn't show the new state until I resize the window manually!

I searched about this problem and come with more than one solution but nothing worked with me:

[myView setNeedsDisplay:YES];
[myView display];
[[myView.window contentView] setNeedsDisplay:YES];


[mySubView1 setHidden:YES]; || [mySubView1 removeFromSuperView];

I even defined myView as Outlet, and nothing work.

and this is my code

if (appState == 1) {

    [self.splitView setFrameSize:CGSizeMake(self.splitView.frame.size.width, self.view.frame.size.height - 250)];

    [self.mySubView1 setHidden:NO];
    [self.mySubView2 setHidden:YES];

    [self.mySubView2 removeFromSuperview];
    [self.mySubView1 addSubview:self.inCallView];
}
else
{
    [self.splitView setFrameSize:CGSizeMake(self.splitView.frame.size.width, self.view.frame.size.height - 70)];

    [self.mySubView1 setHidden:YES];
    [self.mySubView2 setHidden:NO];

    [self.mySubView1 removeFromSuperview];
    [self.mySubView2 addSubview:self.chatHeaderView];
}
// I need to redraw here
[self.view setNeedsDisplay:YES];
[self.mySubView1 setNeedsDisplay:YES];
[self.mySubView2 setNeedsDisplay:YES];
// and nothing happened until I resize my window manually 
Was it helpful?

Solution

I found it, the code is just fine and no need to call any redraw method, the only problem Any UI action need to be done in the MAIN thread

so the final code will be:

dispatch_async( dispatch_get_main_queue(), ^{
    if (appState == 1) {
        [self.splitView setFrameSize:CGSizeMake(self.splitView.frame.size.width, self.view.frame.size.height - 250)];

        [self.mySubView1 setHidden:NO];
        [self.mySubView2 setHidden:YES];
    }
    else
    {
        [self.splitView setFrameSize:CGSizeMake(self.splitView.frame.size.width, self.view.frame.size.height - 70)];

        [self.mySubView1 setHidden:YES];
        [self.mySubView2 setHidden:NO];
    }
});

Thanks, guys.

OTHER TIPS

doing a subview remove or add operation will automatically call setNeedsDisplay:YES so it's no surprise that calling it manually is having no effect.

some things to check:

  1. Check your view properties for nil values. I see you are removing the view which will cause the superview to release it and if you aren't retaining it with a strong property (or elsewhere) it will be deallocated.
  2. Be sure that you aren't fighting autolayout. turn off autolayout temporarily to confirm it is not causing your problem.
  3. you are only setting the frame size. you need to make sure it has the expected origin as well.

Also if you are removing the view you don't need to bother calling setHidden:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top