Xibless weird values from this.ContentView.Frame.Size.Height

RuffinRuffin USMember ✭✭
edited January 2015 in Xamarin.Mac

I'm trying to position items on an NSWindow using Xibless code, and when I try to base height off of this.ContentView.Frame.Size.Width I'm getting strange results.

I've sized the NSWindow by editing MainWindow.xib from a default project in two places:

<string key="NSWindowRect">{{10,10}, {1000, 500}}</string>
<string key="NSFrameSize">{1000, 500}</string>

That seems to work fine.

The only other changes come in MainWindow.cs, where I put this code in Initialize:

    // Shared initialization code
    void Initialize ()
        float fltFullHeight = this.ContentView.Frame.Size.Height;
        float fltFullWidth = this.ContentView.Frame.Size.Width;

        Console.WriteLine (string.Format(
            "This window is {0} points wide and {1} points high", 

        int xSpacer = 10;
        int ySpacer = 10;
        int fromBottom = ySpacer;

        this.BackgroundColor = NSColor.Blue;

        int intTextViewHeight = ((int)fltFullHeight - (3 * ySpacer)) / 2;
        Console.WriteLine (intTextViewHeight);

        //intTextViewHeight = 265;

        Rectangle rRawHtml = new Rectangle (10, fromBottom, (int)fltFullWidth / 2 - (3 * xSpacer), intTextViewHeight);
        NSTextView txtRawHtml = new NSTextView (rRawHtml);
        this.ContentView.AddSubview (txtRawHtml);

        fromBottom += intTextViewHeight + ySpacer;

        Rectangle rEditor = new Rectangle (10, fromBottom, (int)fltFullWidth / 2 - (3 * xSpacer), intTextViewHeight);
        NSTextView txtEditor = new NSTextView (rEditor);
        this.ContentView.AddSubview (txtEditor);

So I'm trying to put two NSTextViews on the left half of the window, splitting the height in half (minus 10 points of space between each and the top and bottom).

To double check, I'm taking the full height (500) minus three 10 point spacers (30), which gives us 470 points for the NSTextViews, divided by two is 235 a piece.

The problem is that though the reported fltFullHeight is reported as 500 in the Console.WriteLine, just as I've set in MainWindow.xib, using that value leaves a huge gap at the top (I'm placing NSTextViews from bottom to top b/c of the way Cocoa sets up its coordinate plane). Unless I've done something idiotic mathematically (and I may have), seems that oughta work.

I'm attaching what I see.

If I set hard code the NSTextView height to 265, things seem to work great.

Where did those extra 2 * (265-235) = 60 points of space come from? Is ContentView not what I want? It's reporting the height I expected. ??


Best Answer


  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    It sounds as if you are editing the xib file directly via a text editor instead of using Xcode. If so, this is a very dangerous idea, and one I would not recommend. Various items in the xib are interdependent and you can easily create "impossible" situations this way.

    When I create a new Xamarin.Mac project, drop that code into the Main Window's initialize, and edit the window default size in Xcode, I'm able to get what I believe you are expecting. I would consider starting a new project and try editing the nib in Xcode.

    As a side note, since you are dealing with an object that is being instanced up inside a nib file, you normally set properties in it via:

        public override void AwakeFromNib ()
  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    If you want to skip using Xcode as much as possible, you can change all of the relevant properties in the various awaken from nib methods and do almost nothing in Xcode.

  • RuffinRuffin USMember ✭✭

    It sounds as if you are editing the xib file directly via a text editor instead of using Xcode. If so, this is a very dangerous idea, and one I would not recommend. Various items in the xib are interdependent and you can easily create "impossible" situations this way.

    That's right -- I edited the xib by right-clicking on MainWindow.xib and selecting "Open With >>> Source Code Editor".

    So I took your advice and tried setting a size for the window, but it looks like I needed to "stretch" the ContentView to match. Is that what you expected?

        // Shared initialization code
        void Initialize ()
            this.MinSize = new Size (1000, 500);
            this.ContentView.SetFrameSize (new SizeF (1000, 480));

    I moved the balance to AwakeFromNib.

    I did have to scale the ContentView's height down (about 20) to take into account the title bar, but otherwise that worked. I don't see any other "awaken from nib methods" in NSObject, but I'll keep digging around.


  • RuffinRuffin USMember ✭✭
    edited January 2015

    SetFrame did the trick. Apologies for not catching that in the Assembly Browser.

    Or the tl; dr; is to double click the xib files in your project to open Xcode and hit save and quit when you are done in Xcode to sync.

    Yep, that's actually what I did to figure out what numbers [I thought] needed to change. I changed size, edited, and diffed the xib changes from XCode in another project. I was really surprised how much the xib changed from the stock MonoMac project xib after XCode was done processing it. I'll attach a quick screenshot, just for fun.

    I'd run through the Hello, Mac and, before that, the Hello iOS tutorials, and man, the syncing between XCode and Xamarin Studio is not particularly fast. As you say, it really is better to do all your edits in XCode first, quit, and give Xamarin Studio a second to catch up. I know it tries to stay current, as Hello, Mac suggests...

    Now that we have our Outlets wired up, let’s save the files and switch back to Xamarin Studio to actually do something interesting with them.

    (That is, the tutorial doesn't say "quit" but "save", implying you'd do work in both simultaneously.) But in my experience, I often fire up my app with command-return "too quickly" and dom't see the XCode changes. Seems sometimes if I did it too quickly, I'd lose the changes, but I'm really doing MonoMac & iOS play in fits and starts; I could be misremembering. I can't say wiring up outlets is much fun either, especially when it's so much easier to do in code.

    If AutoLayout isn't easy to do in xibless-land, I'll probably end up coding up at least a GridLayout equivalent -- though a series of BorderLayouts usually ends up being more useful -- instead of always employing "bespoke" xibless placement, but it's really not that bad.

    Doing things xibless seems much more efficient and provides better control, especially if you want the widgets to move around dynamically once the app starts.

    Thanks again. I'm slowly trying to hack up a good cradle-to-grave tutorial for making a [exceptionally poorly featured] Markdown editor, since the gap between Hello, Mac and "I'm stuck in the Cocoa docs again, translating to C#" is really a pretty big one. Your responses on the forums in particular have made getting moving with MonoMac a heck of a lot easier than it was a year or two ago when I last tried.

Sign In or Register to comment.