UICollectionView scroll if vertical, move cell if horizontal - ios

I have a UICollectionView that scrolls vertically but only if I am not touching a cell or it's content.
UICollectionView -> UICollectionViewCell -> UIView
The UIView has a pan gesture
- (void)move:(UIPanGestureRecognizer*)recognizer{}
which I use to move the UIView around. If the UIView is in the UICollectionView it is restricted to only horizontal movement. If I move the UIView out of the bounds of the UICollectionView then it is removed from the collection.
I want the UICollectionView to scroll vertically if I am moving my finger vertically, which would have to cause the touch events on the UIView to be ignored. But if I move horizontally the touch events will not be ignored on the UIView.
I can't seem to figure out how to accomplish this. Advice would be greatly appreciated.

Related

Why does my UITableView need to be below UIButton in the scene outliner

I have an UIView with a UIButton and a UITableView. I constrained the UIButton (left, top, right, bottom) to (0,0,0,-) with a height of 50px. Below i constrained the UITableView (left, top, right, bottom) to (0,0,0,0) so that the screen would be filled with both views as such:
In this case the UIButton is above the UITableView in the scene outliner:
However whenever I reorder the view in the UIView so that the TableView is above the UIButton in the Scene Outliner it also moves my UITableViewCells but not my UITableView:
The constraints are the same and nothing is moved except for the layering in the scene outliner. Why do my UITableViewCells move down whenever i place my UITableView above my UIButton?
Interface Builder does that when "Adjust Scroll View Insets" in view controller attributes is checked.

UIScrollView and PanGestureRecognizer

I’m have a view that contains a regular UIView and a UIScrollView. The UIView sits above the UIScrollView offscreen. The UIScrollView typically occupies the entire screen. (It should be noted that I’m not using Autolayout). When the user scrolls to the top of the scrollview content I would like the UIView to start appearing on the screen. And when it reaches a certain threshold have the UIView snap into place and occupy the screen.
My initial thought was to use the UIScrollView delegate method, and adjust the superview.frame.orgin.y value when the scrollview contentOffset.y value is negative.
func scrollViewDidScroll(scrollView: UIScrollView) {
pullDownInProgress = scrollView.contentOffset.y <= 0.0
if pullDownInProgress {
self.view. = (-self.view.height / 2) - scrollView.contentOffset.y
}
}
However, this creates a stretching between the UIView and the UIScrollView due the scrollview bounce setting. If I turn off the bounce setting then the scrollview.contentOffset is never less then zero, therefore my superview frame is never adjusted.
Any suggestions on how to accomplish this?
You don't need to change the superview.frame, instead move the offscreen view down by its height so that it can appears and any bouncing effect for the scroll view might be hidden by that view.Or you can even move both the scroll view and the offscreen view with the height of the offscreen view. It really depends whether your offscreen view is transparent or not

Can't scroll both UIScrollView in UITableViewCell and the UITableView itself

My pure AutoLayout UITableViewCell looks like this in Interface Builder:
UITableViewCell
|-> UITableViewCell.contentView
|-> UIView (ScrollViewContainerView)
|-> UIScrollView
|-> left (fixed)
|-> center (fill remaining)
|-> right (fixed)
The UIScrollView contains a left, center, and right UIView. left and right are both fixed width, while center expands to fill the remainder of the UIView. The UIScrollView constraints are to align all edges to ScrollViewContainerView. ScrollViewContainerView constraints are to align all edges to the UITableViewCell.contentView. I have a constraint on center's width to be a multiple of ScrollViewContainerView's width, so the UIScrollView scrolls left and right, but the height is fixed and does not scroll. Note that the UIScrollView has been subclassed to include this code so that the UITableView can detect a tap on the cell to toggle selection.
The issue is that I currently can either scroll the UITableView containing these UITableViewCells up and down or I can scroll the UIScrollViews in the UITableViewCells left and right, not both.
When ScrollViewContainerView.userInteractionEnabled == YES, I can't scroll the UITableView up and down, but I can scroll the UIScrollView left and right. When ScrollViewContainerView.userInteractionEnabled == NO, I can scroll the UITableView up and down, but I can't scroll the UIScrollView left and right. userInteractionEnabled == YES on everything else in the above hierarchy.
I can get away with having ScrollViewContainerView as a sibling view to the UIScrollView (making the UIScrollView the direct descent of contentView -- can't get rid of this view completely, because I require it to get the dimensions for the UIScrollView frame). In that case, the opposite handling with userInteractionEnabled holds.
I know I've done this before in other projects before, but starting fresh again, I can't seem to figure out what step I'm missing. Currently using Xcode 6 6A215l targeting iOS 8, though I have reproduced the issue under Xcode 5 targeting iOS 7.
It sounds like the scrollview is causing your tableview to not allow userInteraction when being scrolled. I'm sure that if you called - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView in the UIScrollView delegate (not sure for iOS 8), but you could just do
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
if(scrollView.dragging == YES) {
self.<scrollViewName>.userInteractionEnabled = NO;
}
}
This is untested code, but it's just a bit of help to get you where you need to go.
Hope it helps!
I met some similar problem.
I have a scrollView in tableViewCell. All works fine.
Until one day, someone told me that the tableView can't scroll up/down when finger is touched on the scrollView in 6p. Just in 6p, not in 5, 5s,or6.
This makes me almost crazy.
Finally, I set the scrollView's height smaller than the height in storyboard.
Biu ~ It works~~~
Still, I don't know why.
#user2277872's answer put me on the right track to look at the output of the UIScrollView delegate methods of the UIScrollView in my UITableViewCell subclass. Putting an NSLog() in scrollViewWillBeginDragging: made me notice that the UIScrollView was receiving scrolling events while I was trying to scroll the UITableView. My UIScrollView had a contentSize larger than its frame in both directions, but I've forced that view to only scroll horizontal, so ignored the height and reset it. That force was my undoing and I should have known it at the time -- the correct solution is to fix the frame height. If the UIScrollView doesn't think there is more vertical content, it will correctly forward the swipe up/down gesture to the UITableView.
While I attempt to figure out why my contentSize is too large when it wasn't before (thinking I'm missing a clipToBounds somewhere), what I'm doing to force horizontal scrolling temporarily is (in the UITableViewCell's subclass):
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGSize contentSize = self.scrollView.contentSize;
contentSize.height = self.frame.size.height;
self.scrollView.contentSize = contentSize;
}
EDIT: Actually, this is seemingly better than overriding drawRect. This would be in the UIScrollView subclass:
/*
* Lock to horizontal scrolling only.
*/
- (void)setContentSize:(CGSize)contentSize
{
[super setContentSize:CGSizeMake(contentSize.width, 1)];
}
The height struct member isn't too important, as long as it's guaranteed to be smaller than the frame.size.height of the UITableViewCell. Still hacky, still need to find why I could clip before and not now.

Horizontal dragging of UIScrollView

I have a subclass of UIScrollView class and this scroll have vertical content. But I need drag and drop this UIScrollView in the parent view on horizontal direction. How can I implement this?
You must have a specific hierarchy:
Before you do anything you must go to your StoryBored and deselect the Autolayout option under the FileInspector.
View
ScrollView
ContainerView (if you want one or have one)
View
UIControl (if you have one)
THE CONTENTS OF YOUR VIEW.
You must however make a declaration of the scrollView in your header file:
IBOutlet UIScrollView *yourScrollViewName;
In your main under viewDidLoad:
-(void)viewDidLoad {
yourScrollViewName.translatesAutoresizingMaskIntoConstraints = NO;
[yourScrollViewName setScrollEnabled:YES];
[yourScrollViewName setContentSize:CGSizeMake(320 ,554)]; //320 is the x which is the width. change this to make it horizontal.
//554 is the Height this has to be larger that the screen size in order to have vertical scrolling.
[yourScrollViewName setPagingEnabled:NO];
}

ios UIScrollview pass scroll event to superview

I have a UIView, and the UIView can detect a pan gesture to move this UIView to left. then I add a scrollview to this UIView, and this scrollview also can move to left and right(scroll's method), in the scrollview view, I add a UITableView that can scroll up and down and The UITableCell can detect UITapGesture.
If I not use UIScrollView, when scroll the tableview to left(the tableview can not scroll to left), the UIView can detect the pan gesture and move to left, but if I use the UIScrollView, when I scroll the tableview ,the move event is detected by the UIScrollView and can not pass to it's superview ,the UIView.
How can I do to pass the move event to the UIView if the UIScrollView can not scroll because It's contentoffset.x == 0 and can not scroll to left, So my UIView can detect the pan gesture and move to left.
Thank you!

Resources