Replace SubView are not visible on NSViewController

gbk3gbk3 Kyryl HorbushkoUSMember ✭✭
edited September 4 in Xamarin.Mac

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

  • all operation on main thread
  • layoutSubiew and other similar methds not help
  • frame is correct
  • if I check in console - all object added as expected:

    • > this.splitContentHolder.RightHolderView.Subviews
      {AppKit.NSView[1]}
      [0]: {}

but i see previous "freezed" NSView from prevViewController - looks like it's not redrawed

  • when i resize View - everything become white (as bg color of presenting View)

Can someone advice - why I cant change subview more that few times?

Answers

  • DavidLilleyDavidLilley David Lilley USMember ✭✭✭

    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

  • gbk3gbk3 Kyryl Horbushko USMember ✭✭

    @DavidLilley Unfortunately I can't share project
    Remove constraint action are not required due to this.

    Calling this method removes any constraints that refer to the view you are removing, or that refer to any view in the subtree of the view you are removing

    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...

  • TimothyRisiTimothyRisi Timothy Risi USXamarin Team Xamurai

    If you can't share the actual project, can you create a basic project that demonstrates the same issue?

  • gbk3gbk3 Kyryl Horbushko USMember ✭✭

    I also found, that next code retain view and never release it

            private void SetupSubview()
            {
                NSArray array = new NSArray();
                NSBundle.MainBundle.LoadNibNamed(this.NibNameForView(), this, out array);
                for (uint i = 0; i < array.Count; i++)
                {
                    this.subView = Runtime.GetNSObject(array.ValueAt(i)) as NSView;
                    if (this.subView != null)
                    {
                        this.subView.TranslatesAutoresizingMaskIntoConstraints = false;
                        this.AddSubviewWithConstaint(this.subView);
                        break;
                    }
                }
            }
    

    where

            private NSView subView;
    

    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...)

  • TimothyRisiTimothyRisi Timothy Risi USXamarin Team Xamurai
    edited September 8

    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)

  • gbk3gbk3 Kyryl Horbushko USMember ✭✭

    @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.

  • ChrisHamonsChrisHamons Chris Hamons USXamarin Team Xamurai

    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.

Sign In or Register to comment.