NSScrollView not working

PreranaPrerana INMember ✭✭

I have taken a scrollview(added using IB), I am adding a new view on every button click.The issue is view inside scrollview doesn't get scrolled. Do we programmatically have to do something to make it scroll??..
What am I missing??

Following are the code snippets:-

Adjusting the layout of the View


        public void layout()
    {
        NSView[] subviews = simpleview.Subviews;
        PointF curPoint;
        curPoint = new PointF(simpleview.Bounds.Size.Width / 2.0f, 0.0f);
        foreach (NSView subview in subviews) 
        {
            RectangleF frame = new RectangleF (curPoint.X - 453.0f / 2.0f, curPoint.Y, 453.0f, 60.0f);
            animateView (subview, frame);
            curPoint.Y += frame.Size.Height + SEPARATION;
        }

    }

       private RectangleF integralRect (RectangleF rect) 
    {
        return simpleview.ConvertRectFromBase(simpleview.ConvertRectToBase(rect));  
    }

                private void animateView(NSView subView, RectangleF toFrame) 
    {
        #if true
        // Simple animation: assign the new value, and let CoreAnimation
        // take it from here

        ((NSView) subView.Animator).Frame = toFrame;
        #else
        //
        // Performing the animation by hand, every step of the way
        //
        var animationY = CABasicAnimation.FromKeyPath("position.y");
        animationY.To = NSNumber.FromFloat(toFrame.Y);
        animationY.AnimationStopped += delegate {
        //Console.WriteLine("animation stopped");
        subView.Layer.Frame = toFrame;
        };

        var animationX = CABasicAnimation.FromKeyPath("position.x");
        animationX.To = NSNumber.FromFloat(toFrame.X);

        animationY.AutoReverses = false;
        animationX.AutoReverses = false;

        animationY.RemovedOnCompletion = false;
        animationX.RemovedOnCompletion = false;

        animationY.FillMode = CAFillMode.Forwards;
        animationX.FillMode = CAFillMode.Forwards;

        subView.Layer.AddAnimation(animationX,"moveX");
        subView.Layer.AddAnimation(animationY,"moveY");
        #endif
    }

Adding a new view on buttonclick

      partial void Addbutton (NSObject sender)
    {
        simpleview.AddSubview(new UserControlController().View);
        layout();
    }

Basically my view is not getting drawn and my scrollbars are not enabled too.

Note: The above code is based on AnimatingViews from xamarin mac samples.

Thanks in advance!

Best Answer

  • JGoldbergerJGoldberger USXamarin Team, University Xamurai
    Accepted Answer

    @SteveFlack,

    Try adding

    scrollViewOutlet.ContentView.ScrollRectToVisible(toFrame);
    

    immediately after

    ((NSView) subView.Animator).Frame = toFrame;
    

    in the animateView method.

    I hope this helps.

    All the best

    Jon

Answers

  • SteveFlackSteveFlack GBMember ✭✭
    edited December 2013

    Sadly NSScrollViews (like NSTableViews) on the Mac are not as nice to use as their iOS equivalents. Scrolling NSScrollViews with animation actually requires you to scroll the enclosed NSClipView (in objective-C I'd set it's bounds using it's animator proxy) and then flashing scrollbars manually.

  • PreranaPrerana INMember ✭✭

    Hey @Steve,

    Even i read about that clip view. NSClipView means the view between the scrollbar right?,the NSView that comes along with Scrollview ??


    Can you suggest a workaround for this in Xamarin.Mac?

    Thanks for your answer!

  • SteveFlackSteveFlack GBMember ✭✭

    I don't have a C# version (yet) but this works for NSTableViews in Objective-C. How well it translates I don't know. It's in an objc-c category on NSTableView.

    - (BOOL)isRowVisible:(NSInteger)row
    {
        if (row>=self.numberOfRows) return NO;
        NSRect rowRect=[self rectOfRow:row];
        rowRect.size.width=self.visibleRect.size.width;
        return NSContainsRect(self.visibleRect, rowRect);
    }
    
    - (void)scrollRowToVisible:(NSInteger)rowIndex animate:(BOOL)animate
    {
        if ([self isRowVisible:rowIndex]) {
            return;
        }
    
        if (animate) {
            NSRect rowRect = [self rectOfRow:rowIndex];
            NSPoint scrollOrigin = rowRect.origin;
            NSClipView * clipView = (NSClipView *)self.superview;
            scrollOrigin.y += MAX(0, round((NSHeight(rowRect) - NSHeight(clipView.frame)) * 0.5f));
            NSScrollView * scrollView = (NSScrollView *)clipView.superview;
            if ([scrollView respondsToSelector:@selector(flashScrollers)]) {
                [scrollView flashScrollers];
            }
            [[clipView animator] setBoundsOrigin:scrollOrigin];
        } else {
            [self scrollRowToVisible:rowIndex];
        }
    }
    

    Markdown code tag support for objective-c is incredibly poor so sorry for the dodgy formatting.

  • PreranaPrerana INMember ✭✭

    Thanks @Steve , I will try to figure it out..:)

  • JGoldbergerJGoldberger USXamarin Team, University Xamurai
    Accepted Answer

    @SteveFlack,

    Try adding

    scrollViewOutlet.ContentView.ScrollRectToVisible(toFrame);
    

    immediately after

    ((NSView) subView.Animator).Frame = toFrame;
    

    in the animateView method.

    I hope this helps.

    All the best

    Jon

  • SteveFlackSteveFlack GBMember ✭✭

    @Jgoldberger wrong guy. I think you need to aim this at @Prerana

  • JGoldbergerJGoldberger USXamarin Team, University Xamurai
    edited January 2014

    Oops, yup, sorry.

    Prerana actually had an email support case going for this issue, I just posted the answer here for the benefit of future visitors. :-)

  • PreranaPrerana INMember ✭✭

    Hey @Jgoldberger,

    Thanks a ton, its definitely better than what I had before..:)

    Thanks again..:):)

Sign In or Register to comment.