Tracking frame.origin.x in UIPageController while scrolling - cocoa-touch

I'm using standard UIPageViewController here and I need to track x coordinate in order to change the alpha of the image accordingly. I try to find the UIScrollView in UIPageViewController like this and it works:
for (UIView *view in self.pageViewController.view.subviews) {
if ([view isKindOfClass:[UIScrollView class]]) {
[(UIScrollView *)view setDelegate:self];
}
}
But when I do this:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
MTWPageContentViewController *pageContentVC = [self viewControllerAtIndex:_mainPageControl.currentPage];
NSLog(#"%f", pageContentVC.view.frame.origin.x);
}
NSLog gives me 0.000 which obviously means that I'm doing something wrong.
pageContentVC exists and it is the view controller visible at the moment I scroll.
So, tell me how do I track x coordinate of UIPageViewController's subview while scrolling?

You can grab the gesture recognisers from the UIPageViewController and add yourself as a target/action to get information about the pan.
for (UIGestureRecognizer *gestureRecognizer in self.pageViewController.gestureRecognizers) {
if ([gestureRecognizer isKindOfClass:UIPanGestureRecognizer.class]) {
[gestureRecognizer addTarget:self action:#selector(panned:)];
}
}

Related

Rotation Gesture on UIScrollView

I am working on Scroll View with gestures. I added a UIView in Scroll View whose size is equal to the ScrollView content size. I want to apply the pinch gesture and rotate gesture on the View which is subview of ScrollView. I have done the work of the pinch gesture by using zoom property and delegate of the ScrollView which give me same effect which I want. But Rotation Gesture is creating Problem. When I add rotation gesture on the view then zooming of the scroll view also get disturb.
So how can i apply the pinch gesture and Rotate gesture on the Scroll View's subview whose size must be equal to the content size of the ScrollView initially.
Can anybody give me the way to do this!
This is the code of .m file, when we rotate the view it become invisible
#import "ViewController.h"
#interface ViewController ()
{
UIView *backgroundView;
UIScrollView *scrollView;
CGFloat lastRotation;
}
#end
#implementation ViewController
-(void)loadView
{
[super loadView];
//Scroll View
scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
scrollView.contentSize = self.view.frame.size;
scrollView.delegate = self;
scrollView.backgroundColor = [UIColor grayColor];
//Zooming factors of the Scroll View
scrollView.minimumZoomScale = 1.0;
scrollView.maximumZoomScale = 5.0f;
scrollView.zoomScale = 1.0;
[self.view addSubview:scrollView];
//Scroll View's subview
backgroundView = [[UIView alloc] initWithFrame:scrollView.frame];
[backgroundView setBackgroundColor:[UIColor orangeColor]];
[scrollView addSubview:backgroundView];
UIRotationGestureRecognizer *bgRotationGstr = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotateBackgroundView:)];
bgRotationGstr.delegate = self;
bgRotationGstr.cancelsTouchesInView = NO;
[backgroundView addGestureRecognizer:bgRotationGstr];
//Child of background view
UIView *childView = [[UIView alloc] initWithFrame:CGRectMake(20, 50, 100, 100)];
childView.backgroundColor = [UIColor grayColor];
[backgroundView addSubview:childView];
}
//Rotation of the background view
-(void)rotateBackgroundView:(UIRotationGestureRecognizer*)gesture
{
CGFloat rotation = 0.0 - (lastRotation - [(UIRotationGestureRecognizer*)gesture rotation]);
CGAffineTransform currentTransform = backgroundView.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[backgroundView setTransform:newTransform];
lastRotation = [(UIRotationGestureRecognizer*)gesture rotation];
if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged)
{
scrollView.scrollEnabled = NO;
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
lastRotation = 0.0;
scrollView.scrollEnabled = YES;
return;
}
}
#pragma mark<UIScrollViewDelegate>
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return backgroundView;
}
#pragma mark<UIGetsureRecognizer>
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
return YES;
}
#end
After many days of struggling I found a definitive solution in order to use UIScrollView integrated zoom behavior together with UIRotationGestureRecognizer working like a charm. You have to add a container dummy view as subview of the scroll view, and put the UIImageView as subview of the container view. Afterthat, return the container view in the viewForZoomingInScrollView method and add the UIRotationGestureRecognizer to the scrollview, applying CGAffineTransformRotate to the UIImageView. Finally, return true in the shouldRecognizeSimultaneouslyWithGestureRecognizer method. In this way the scrollView will capture both the two fingers rotation gesture and the pinch to zoom gesture: the zoom will be applied to the dummy view and rotation to the uiimageview, without conflicts between transformations.
In code: let's think to have a UIViewController presenting a UIScrollView. We want to use scrollview's zoom behaviour out of the box together with UIImageView rotation.
1) The controller (or any other object) containing UIScrollView must conforms to UIGestureRecognizerDelegate protocol.
In myViewController.h
#interface myViewController : UIViewController < UIGestureRecognizerDelegate> {
}
2) Create a UIScrollView, add a dummy view as subview and finally add a UIImageView as subview of the dummy view.
In myViewController.m
//Scrollview
myScrollView=[[UIScrollView alloc] initWithFrame:CGRectMake(0,0, view.frame.size.width, view.frame.size.height)];
myScrollView.delegate=self;
[view addSubview:myScrollView];
//Dummy View
UIView *dummyView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, myScrollView.frame.size.width, myScrollView.frame.size.height)];
[self addSubview:dummyView];
//ImageView
imageView=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, dummyView.frame.size.width, dummyView.frame.size.height)];
imageView.contentMode=UIViewContentModeScaleAspectFit;
[dummyView addSubview:imageView];
//Add rotation gesture to the scrollView
rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(handleRotate:)];
[myScrollView addGestureRecognizer:_rotationGestureRecognizer];
//Set the controller as delegate of the recognizer
rotationGestureRecognizer.delegate=self;
[...]
#pragma UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
//Set the dummy view (imageview's superview) as view for zooming
return imageView.superview;
}
[...]
#pragma Mark - UIGestureRecognizerDelegate
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
//Make it possibile to recognize simultaneously pinch and rotation gestures
return TRUE;
}
[...]
- (IBAction) handleRotate:(UIRotationGestureRecognizer*)recognizer {
//Apply the rotation to imageView
imageView.transform = CGAffineTransformRotate(imageView.transform, recognizer.rotation);
recognizer.rotation = 0;
}
For simplyfing purposes, I wrote everything in the same controller. You are free to subclass the UIScrollView. Remember that the tricks are:
1) returning the container dummy view as viewForZoomingInScrollView so zoom will affect the container view and rotation will affect the uiimageview.
2) set the viewcontroller containing the scrollview as delegate of the rotation gesture recognizer and return TRUE for shouldRecognizeSimultaneouslyWithGestureRecognizer.
Add this to your .m
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
Also make sure you dont have exclusive touch enabled on any gesture recognizers.
Try to put you scalable/rotatable content in a subview of your content view. ( Maybe you must set the "clip content" property of your content view to true - not sure )
This way the scrollview is not concerned anymore by transformations, since its content view stays still.
If you have to display the clipped content ( if you rotate a square, for example, the corners go out the initial area), recompute your content view and update the scrollview.
Since you gave the code, I suggest to try:
//Scroll View's subview
backgroundViewHolder = [[UIView alloc] initWithFrame:scrollView.frame];
[backgroundViewHolder setBackgroundColor:[UIColor orangeColor]];
[scrollView backgroundViewHolder];
//Holder View's subview
backgroundView = [[UIView alloc] initWithFrame:backgroundViewHolder.bounds];
[backgroundViewHolder addSubview:backgroundView];
Everything else should remain the same. This is just an idea... Not sure it is the right answer.
Add this to your implement file, make it a UIGestureRecognizerDelegate.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
rotationGeustureRecognozier.delegate = self;// (the implement file)

The UICollectionView "swipe-away" in iOS7 app manager?

On any 2014+ iPhone or iPad, double-click the home button to see the "app manager"
This is a left-right UICollectionView BUT it has a "swipe-away" gesture .. swipe up. How is it done? It's not so easy to "remove" a cell from a UICollectionView.
Footnote for googlers .. for the general problem of "peeling off", "tearing away", one cell from a collection view, here's a full tidy explanation: https://stackoverflow.com/a/24339705/294884 Hope it helps someone.
It can be much simpler than the comments on your question are suggesting.
Your cell should contain a view (the thing that you're going to drag off) and you add a UIPanGestureRecognizer to that view.
In the gesture's action method, you move the view up or down, and when it gets far enough off that you want to delete it, you just animate it off. There are plenty of questions here dealing with this part.
This leaves a gap in your collection and now you need to move things around. It turns out this is quite simple:
[_collectionView performBatchUpdates:^{
[_collectionView deleteItemsAtIndexPaths:#[indexPath]];
} completion:^(BOOL finished) {
// you might want to remove the data from the data source here so the view doesn't come back to life when the collection view is reloaded.
}];
The stuff to the right of the removed cell slides over and we're all good.
Another problem to get over: making sure your gesture recognizer and the collection view's one play nice together. Thankfully, that's not too tricky either.
[_collectionView.panGestureRecognizer requireGestureRecognizerToFail:pgr]; //where pgr is the recognizer you made for dragging the view off
This means in order for the collection view's pan gesture to do its thing, your one has to fail. So you'll want to set yours up so that it only works when panning up and down, and let the collection view still do its thing for left to right pans. In your gesture recognizers's delegate, implement the following method which simply checks if you're moving more on the x-axis or y-axis.
-(BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
{
CGPoint translation =[gestureRecognizer translationInView:self.view];
return(translation.x * translation.x > translation.y * translation.y);
}
I was looking for this functionality and using #mbehan suggestion i faked this functionality using UICollectionView.
What i did is i added a view of smaller size on a collection cell(Transparent background) and added a single pan gesture on CollectionView(not on each cell) then on pan gesture i move the view and it looks like the cell is moving. After view reaches some point i first hide it and then deletes the collection view cell.
Cell Hierarchy : collectionViewCell -> View(tag value==2) -> UILabel(tag Value == 1)
Label is just used for placeholder purpose.
i am posting my code below:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = (UICollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"Cards" forIndexPath:indexPath];
UILabel *lblNumber = (UILabel*)[cell.contentView viewWithTag:1];
UIView *viewTouch = (UIView*)[cell.contentView viewWithTag:2];
[viewTouch setHidden:NO];
[lblNumber setText:arrCards[indexPath.row]];
return cell;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 50, 0, 30);
}
-(BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer
{
if([gestureRecognizer isEqual:panGesture]) {
CGPoint point = [(UIPanGestureRecognizer*)gestureRecognizer translationInView:collectionView_];
if(point.x != 0) { //adjust this condition if you want some leniency on the X axis
//The translation was on the X axis, i.e. right/left,
//so this gesture recognizer shouldn't do anything about it
return NO;
}
}
return YES;
}
- (IBAction)panGestureCalled:(UIPanGestureRecognizer *)sender {
yFromCenter = [sender translationInView:collectionView_].y; //%%% positive for up, negative for down
UIView *view = sender.view;
CGPoint location = [view.superview convertPoint:view.center toView:collectionView_];
NSIndexPath *indexPath = [collectionView_ indexPathForItemAtPoint:location];
UICollectionViewCell *cell = [collectionView_ cellForItemAtIndexPath:indexPath];
UIView *touchView = (UIView*)[cell.contentView viewWithTag:2];
switch (sender.state) {
case UIGestureRecognizerStateBegan:{
originalPoint = touchView.center;
break;
};
case UIGestureRecognizerStateChanged:{
touchView.center = CGPointMake(originalPoint.x , originalPoint.y + yFromCenter);
break;
};
//%%% let go of the card
case UIGestureRecognizerStateEnded: {
CGFloat velocityY = (0.2*[(UIPanGestureRecognizer*)sender velocityInView:collectionView_].y);
if (velocityY < -30 && yFromCenter<0) {
[self hideView:touchView withDuration:0.2 andIndexPath:indexPath];
}else if ((yFromCenter< 0 && yFromCenter > -200) || yFromCenter > 0){
CGFloat animationDuration = (ABS(velocityY)*.0002)+.2;
[self resettleViewToOriginalPosition:touchView andDuration:animationDuration];
}else
[self hideView:touchView withDuration:0.2 andIndexPath:indexPath];
};
break;
case UIGestureRecognizerStatePossible:break;
case UIGestureRecognizerStateCancelled:break;
case UIGestureRecognizerStateFailed:break;
}
}
-(void)resettleViewToOriginalPosition:(UIView*)view andDuration:(float)duration{
[UIView animateWithDuration:duration
delay:0.0f
options: UIViewAnimationOptionCurveEaseOut
animations:^
{
[view setCenter:originalPoint];
}
completion:^(BOOL finished)
{
}];
}
- (void)hideView:(UIView*)view withDuration:(float)duration andIndexPath:(NSIndexPath*)indexPath
{
[UIView animateWithDuration:duration
delay:0.0f
options: UIViewAnimationOptionCurveEaseOut
animations:^
{
CGRect frame = view.frame;
frame.origin.y = -300;
view.frame = frame;
}
completion:^(BOOL finished)
{
[view setHidden:YES];
CGRect frame = view.frame;
frame.origin.y = 39;
view.frame = frame;
NSLog(#"View is hidden.");
[arrCards removeObjectAtIndex:indexPath.row];
[collectionView_ performBatchUpdates:^{
[collectionView_ deleteItemsAtIndexPaths:#[indexPath]];
} completion:^(BOOL finished) {
// you might want to remove the data from the data source here so the view doesn't come back to life when the collection view is reloaded.
}];
}];
}
and keep pagingEnabled of CollectionView to NO and then it should be good to go.

How to disable a UITableView from scrolling up vertically?

I'm using EGORefreshTableHeader in conjunction with a static cell (defined in a nib) in a UITableView.
I'd like to be able to scroll the tableview down to trigger the EGORefreshTableHeader and thus refresh the data in the static cell. BUT, as the static cell is sized to fit perfectly in the window, I want to prevent folks from being able to scroll up.
Is there a way to do this?
Try this:
CGFloat a;
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
a = scrollView.contentOffset.y;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y > a)
{
[scrollView setScrollEnabled:NO];
[scrollView setContentOffset:CGPointMake(0, a)];
}
[scrollView setScrollEnabled:YES];
}

detect long press on UINavigationItem's back button

I want to add functionality to my back buttons through my UINavigationController-based app where long-pressing the back button will pop to root. However, I can't figure out where to attach the gesture recognizer. Do I subclass UINavigationBar and try and detect if the long press is in the left button region?
I've heard of people adding similar functionality before. Anyone have any ideas?
I know this question is old, but I came up with a solution. Instead of trying to add the gesture recognizer to the button itself (which would be ideal), I added it to the self.navigationController.navigationBar and then in the action method, use the locationInView to see if I'm over the back button. I wasn't entirely sure about how to identify the back button precisely, so I'm clumsily just grabbing the the first subview with an x coordinate less than some arbitrary value, but it seems promising. If someone has a better way to identify the frame of the back button, let me know.
- (void)longPress:(UILongPressGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateEnded)
{
// set a default rectangle in case we don't find the back button for some reason
CGRect rect = CGRectMake(0, 0, 100, 40);
// iterate through the subviews looking for something that looks like it might be the right location to be the back button
for (UIView *subview in self.navigationController.navigationBar.subviews)
{
if (subview.frame.origin.x < 30)
{
rect = subview.frame;
break;
}
}
// ok, let's get the point of the long press
CGPoint longPressPoint = [sender locationInView:self.navigationController.navigationBar];
// if the long press point in the rectangle then do whatever
if (CGRectContainsPoint(rect, longPressPoint))
[self doWhatever];
}
}
- (void)addLongPressGesture
{
if (NSClassFromString(#"UILongPressGestureRecognizer"))
{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPress:)];
[self.navigationController.navigationBar addGestureRecognizer:longPress];
[longPress release];
}
}
I believe UIGestureRecognizers can only be added to UIViews and subclasses of UIViews.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html
The back button is a UIBarButtonItem that descends from NSObject. Therefore, you won't be able to attach a gesture recognizer to a standard back button using
UILongPressGestureRecognizer *longPressGesture =
[[[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(longPress:)] autorelease];
[self.navigationItem.backBarButtonItem addGestureRecognizer:longPressGesture];
You can however add a custom view to a UIBarButtonItem. A custom view could just as easily be a UIView, UIButton, UILabel, etc.
Example:
UIView *myTransparentGestureView = [[UIView alloc] initWithFrame:CGRectMake(0,0,40,30)];
[myTransparentGestureView addGestureRecognizer:longPressGesture];
[self.navigationItem.backBarButtonItem setCustomView:myTransparentGestureView];
// Or you could set it like this
// self.navigationItem.backBarButtonItem.customView = myTransparentGestureView;
[myTransparentGestureView release];
You have to be careful however, since setting properties on backBarButtonItem applies to the next view that you push. So if you have view A that pushes to view B and you want the gesture to be recognized when you tap back in view B. You must set it up in view A.
I followed a slightly different path, figured I'd share it. The above answers are fine, but really, if the long press is in the leading 1/3 of the nav bar, that's good enough for me:
- (void)longPress:(UILongPressGestureRecognizer *)gr
{
NSLog(#"longPress:");
UINavigationBar *navBar = [self navigationBar];
CGFloat height = navBar.bounds.size.height;
CGPoint pt = [gr locationOfTouch:0 inView:navBar];
//NSLog(#"PT=%# height=%f", NSStringFromCGPoint(pt), height);
if(CGRectContainsPoint(CGRectMake(0,0,100,height), pt)) {
[self popToViewController:self.viewControllers[0] animated:YES];
}
}
Here's my solution:
In appDelegate (the "owner" of the nav bar in my app), In applicationDidFinishLaunchingWithOptions:
Get the nav bar view and add the gesture recognizer to the whole view:
// Get the nav bar view
UINavigationBar *myNavBar = nil;
for (UIView *view in [self.window.rootViewController.view subviews]) {
if ([view isKindOfClass:[UINavigationBar class]]) {
NSLog(#"Found Nav Bar!!!");
myNavBar = (UINavigationBar *)view;
}
}
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self
action:#selector(backButtonLongPress:)];
[myNavBar addGestureRecognizer:longPress];
NSLog(#"Gesture Recognizer Added.");
Then in appDelegate, in -(void) backButtonLongPress:(id) sender
Check to see if the gesture occurs within the frame of the back button:
if ([sender state] == UIGestureRecognizerStateBegan) {
// Get the nav bar view
UINavigationBar *myNavBar = nil;
for (UIView *view in [self.window.rootViewController.view subviews]) {
if ([view isKindOfClass:[UINavigationBar class]]) {
NSLog(#"Found Nav Bar!!!");
myNavBar = (UINavigationBar *)view;
}
}
// Get the back button view
UIView *backButtonView = nil;
for (UIView *view in [myNavBar subviews]) {
if ([[[view class] description] isEqualToString:#"UINavigationItemButtonView"]) {
backButtonView = view;
NSLog(#"Found It: %#", backButtonView);
NSLog(#"Back Button View Frame: %f, %f; %f, %f", backButtonView.frame.origin.x, backButtonView.frame.origin.y, backButtonView.frame.size.width, backButtonView.frame.size.height);
}
}
CGPoint longPressPoint = [sender locationInView:myNavBar];
NSLog(#"Touch is in back button: %#", CGRectContainsPoint(backButtonView.frame, longPressPoint) ? #"YES" : #"NO");
if (CGRectContainsPoint(backButtonView.frame, longPressPoint)) {
// Place your action here
}
// Do nothing if outside the back button frame
}

How to pass scrolling input to a different view

This site really is awesome.
I have what is hopefully a simple question this time. I would like to pass any scrolling input from the user (could be wheel, touchpad, etc) to an NSScrollView which contains my own subviews.
At the moment if the user scrolls just on the documentView (outside of my subviews' frames) the scroll works normally but if they scroll while the cursor is over a subview nothing happens. So basically I'd like to have the subview recognise the scroll event and pass it back to the scroll view.
Any help is greatly appreciated.
Cheers.
EDIT:
Here is the code I'm using to add the subviews to the documentView
_milestoneView and _activityView are both NSView subclasses which have a corresponding nib (created with instantiateNibWithOwner and objects hooked up accordingly) they contain a NSTextField, PXListView and some have a NSProgressIndicator.
-(void)useProject:(NSNumber *)projectId
{
[self resetView];
NSRect bounds = [[self view] bounds];
NSRect defaultFrame = NSMakeRect(20, NSMaxY(bounds)-93, NSMaxX(bounds)-20, 50);
//Prepare the milestone view
if (_milestoneView == nil)
_milestoneView = [MilestoneView milestoneViewFromNibWithFrame:defaultFrame withProject:[BCLocalFetch projectForId:projectId]];
[_milestoneView reloadList];
//Prepare the activity view
if (_activityView == nil)
_activityView = [ActivityView activityViewFromNibWithFrame:defaultFrame withProject:[BCLocalFetch projectForId:projectId]];
[self refresh];
}
I then use the refresh method to reposition them as the content sizes vary so I wanted to have a separate method.
-(void)refresh
{
//Position the milestones first
[_milestoneView setFrameOrigin:NSMakePoint(20, NSMaxY([[self view] bounds])-[_milestoneView frame].size.height-60)];
if ([[_milestoneView milestones] count] > 0)
[[self view] addSubview:_milestoneView];
//Now the activity view
[_activityView setFrameOrigin:NSMakePoint(20, [_milestoneView frame].origin.y-[_activityView frame].size.height-20)];
[[self view] addSubview:_activityView];
[self autosizeView];
}
-(void)autosizeView
{
//Resize the view to accommodate all subviews
NSRect oldFrame = [[self view] frame];
CGFloat lastY = [_activityView frame].origin.y;
if (lastY < 0) {
CGFloat newHeight = oldFrame.size.height + (-lastY);
[[self view] setFrameSize:NSMakeSize(oldFrame.size.width, newHeight)];
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"BBContentDidResizeNotification" object:self];
}
Ok so I came back to the issue and finally got it worked out. The implementation was actually quite simple.
I added a property to PXListView to point to the NSScrollView that is to be scrolled.
I then implemented NSResponder's scrollWheel: method like this:
-(void)scrollWheel:(NSEvent *)theEvent
{
//Pass scrolling to the superview
[_scrollHandler scrollWheel:theEvent];
}
And all is well!