Hi, I have purpose to display few View from different NSViewControllers on one ViewController.
For such purpose I create one controller and on required moment replace View with new one from another VIewController.
On Main (Always exist, at least for current scope) controller I have RootView (View from NSViewController) and PresentingView(Subview on View from NSViewController). All works fine, except if I change View twice or so... I can't figure out where is the problem.
What I use:
Category for AddSubview:
[Category(typeof(NSView))] public static class NSViewSubviewExtension { public static void AddSubviewWithConstaint(this NSView parentView, NSView view) { ArgumentValidator.NotNull(view, () => view); ArgumentValidator.NotNull(parentView, () => parentView); view.TranslatesAutoresizingMaskIntoConstraints = false; parentView.AddSubview(view); var topConstaint = NSLayoutConstraint.Create(view, NSLayoutAttribute.Top, NSLayoutRelation.Equal, parentView, NSLayoutAttribute.Top, 1, 0); var bottomConstaint = NSLayoutConstraint.Create(view, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, parentView, NSLayoutAttribute.Bottom, 1, 0); var leadingConstaint = NSLayoutConstraint.Create(view, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, parentView, NSLayoutAttribute.Leading, 1, 0); var trailingConstaint = NSLayoutConstraint.Create(view, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, parentView, NSLayoutAttribute.Trailing, 1, 0); NSLayoutConstraint[] allConstaints = { topConstaint, bottomConstaint, leadingConstaint, trailingConstaint }; parentView.AddConstraints(allConstaints); } }
And method for replaceView
protected void ReplaceView(NSViewController viewController) { if (this.rightContentViewController != null) //this.rightContentViewController - tempCreatedViewController from which i take View { this.rightContentViewController.View.RemoveFromSuperview(); } foreach (NSView obj in this.splitContentHolder.RightHolderView.Subviews) //this.splitContentHolder - MainViewController //this.splitContentHolder.RightHolderView - presentingView { obj.RemoveFromSuperview(); } this.rightContentViewController = viewController; this.splitContentHolder.RightHolderView.AddSubviewWithConstaint(viewController.View); }
Also
if I check in console - all object added as expected:
but i see previous "freezed" NSView from prevViewController - looks like it's not redrawed
Can someone advice - why I cant change subview more that few times?
Answers
Can you provide an example project ? It might be easier to track down your problem.
Also I see you are adding constraints but not removing them, I wonder if that could have any side effects
@DavidLilley Unfortunately I can't share project
Remove constraint action are not required due to this.
So, guess this is not a problem.
As for me, because I'm able to see all objects in debugger, but can't see them on screen, this can be some display-related issue, but as I noted above, I try to force redraw and this not help, at all...
If you can't share the actual project, can you create a basic project that demonstrates the same issue?
I also found, that next code retain view and never release it
where
Also one more strange things is, if i open VS "from scratch" and open xib file, move some view - all works until I relaunch project... Than - it's not work anymore. This is 100% case
PS: I use VS 7.0.1 + Pathc (without path VS cant prepare nib files, this patch provided by Xamarin dev and need to be installed every time after update, in other case nib file will be not created...)
By any chance have you tried loading the project up on a mac and building and running it there to see if the same thing happens (just in case it's some weirdness happening from building in VS)
@TimothyRisi - In xCode all works as expected...
I also found workaround - add 300ms delay before and after changing subview, and all start work. But this is really not preferred solution.
This makes it sound like you either have a race condition or threading issues in your code. You should be responding to lifecycle events from your view or view controller, not guessing a certain amount of time from the outside.