How to get TouchesBegan working on a subView (Child view) rather than on Parent view? - ios

I have a setup like this
Scroll View (Main View) -> CanvasView (SubView) -> Pages (SubView of
Canvas).
I want to add Touches began functionality to Pages , but for it to be detected I had to setUserInteractionEnabled = YES; to every parent view.
Now when I try to look for the view which is being detected I get the view of class UIScrollView.
As you can see in the image I have an UISCrollview on which a black screen whose subview is the white view. I need to do the touches began on the white view.

Related

Scrolling a UIScrollView regardless of where the touch occurs

The end goal is to create the same scrolling effect as the one on the "Me" tab of the twitter iOS app where the segmented control rises to the top as you scroll down and then stays fixed to it unless scrolled back up to the top.
The solution I've come up with is illustrated below. There is a view at the top, a segmented control, and a table view beneath the segmented control. All of these elements are embedded inside a scrollview that takes up the entire screen (minus tab & nav bars).
Here is the key issue: If begin scrolling by swiping up from the top-most view or the segmented control, it scrolls the scrollview that all the elements are embedded in. If I scroll the tableview, it will only scroll itself and leave the top-most view and segmented control unaffected.
How can I scroll the scrollview that the elements are embedded in no matter where the scrolling occurs on screen?
I had a similar layout in one of my projects. I used SJSegmentedViewController.
It Requires a headerViewController ,datasource for middle segment and viewController array for those segments.
This library allows you to scroll from anywhere on the screen moreover the segmented control sticks to the top as user scrolls all the way to top.
Here is how you can implement this :
First import the module into your class
import SJSegmentedScrollView
Then create a headerViewController and two viewControllers(Say Video and Tips) for segment
let headerViewController = HeaderViewController()
let video = VideoController()
let tips = TipsController()
After that set these Controller and also set the title for segmented control as following:
segmentController.headerViewController = header
segmentController.segmentControllers = [video,tips]
video.title = "Video"
tips.title = "Tips"
Then add it to the Container View
addChildViewController(segmentController)
containerView.addSubview(segmentController.view)
segmentController.view.frame = self.containerView.bounds
segmentController.didMove(toParentViewController: self)
Here Container View is a UIContainerView
Last but make sure to call in child controllers (VideoController,TipsController), After calling this function in those controllers you can scroll from anywhere on the screen.
extension HomeListingViewController: SJSegmentedViewControllerViewSource {
func viewForSegmentControllerToObserveContentOffsetChange() -> UIView {
//Scrollview in child controllers
return scrollview
}
}
You can find the full documentation here
Hope this helps!

Swift - Scroll a UIScrollView by tapping button inside a ViewController inside the ScrollView

I have a UIScrollView that contains a bunch of view controllers, and in each view controller there is a button that if pressed, should scroll the UIScrollView to a certain position. How do I go about connecting the viewController IBAction for the button to set the scroll position of the UIScrollView?
I know I'll call contentOffset at some point, but I'm struggling with getting the ViewControllers to control the Scroll View.
One way you could do it... When you add each UIViewController.view to the UIScrollView you could also set a var in each UIViewController that references the UIScrollView.
For example, for some UIViewController, we'll call it X, put
var scrollView: UIScrollView?
in it. Then in your class that controls the UIScrollView, when you add view X to the UIScrollView, also do the following:
viewControllerX.scrollView = self.theScrollView
Now, when your IBAction method is called in viewControllerX, you have a reference to the UIScrollView and as you said, can do self.scrollView.contentOffset.y = someValueHere to change its position.

Hiding parentView and subviews rather then the last added subview

I have custom parent view, which is a sub class UIView with some UIImageView's, UILabel's etc..
I add as a subview screenshot of it.I would like to hide all the subviews and the parent view rather then that screenshot.
Any help on this is appreciated.
Code:
self.temp = [self snapshotViewAfterScreenUpdates:NO];
self.temp.frame = self.bounds;
[self addSubview:self.temp];
I hope the screenshot is one of the subview of your parent view. So hiding the parent view will hide all the subviews including the screenshot.
You can do the following
Make the screenshot size, bound to the parent and add to top
Present the screenshot as a popover/modal-view and blur the parent view
Remove/hide all the subviews from the parent except the screenshot

ScrollView - Send Touches to View below

My setup - and I cannot change it - is right now:
Root View
- UIView
-- ScrollView2
- ScrollView1 (this is top in view hierarchy)
The first scrollview is used to apply some transitions on the below UIView. The second scrollviews contentoffset (captures in scrollViewDidScroll:) is used to apply other animations.
Question: How can I transfer/delegate all touches from ScrollView1 to ScrollView2? Please note that the ScrollView1 is on top of everything and the others views are below of it - not subviews!
You can add the pan gesture recogniser from a scroll view to any other view you want and this will effectively delegate the touches from the targeted view to the scroll view. You can also add the pinch gesture recogniser if you want to control zoom.

Drag a UIView from one UIScrollView to another

I have two UIScrollViews on my screen and I need to be able to drag a UIView from one scrollview to the other.
At the moment, I have a UILongGestureRecognizer on the UIView that I want to move, such that when the user starts dragging it, I make the view follow the touch:
- (void)dragChild:(UILongPressGestureRecognizer *)longPress {
[[longPress view] setCenter:[longPress locationInView:[[longPress view] superview]]];
}
But when I get the boundary of the starting UIScrollView, the view disappears because it's locked into that scrollview's bounds.
Is there a way to "pop" it out of the scrollview when I start dragging such that I can carry it over to the other scrollview?
Also, how do I test for the "drop" location? I want to know if it's been dropped over a certain other view.
Or am I going about this all the wrong way?
Thanks guys
If you will need to drag it from a scroll view to another do the following (pseudo code)
when you start dragging do the following
//scrollView1 is the scroll view that currently contains the view
//Your view is the view you want to move
[scrollView1.superView addSubView:yourView];
now when dropping the view, you will need to know if it is inside the other scrollview
//scrollView2 is the second scroll view that you want to move it too
//Your view is the view you want to move
CGPoint point = yourView.center;
CGRect rect = scrollView2.frame;
if(CGRectContainsPoint(rect, point))
{
//Yes Point is inside add it to the new scroll view
[scrollView2 addSubView:yourView];
}
else
{
//Point is outside, return it to the original view
[scrollView1 addSubView:yourView];
}
Here is an untested idea:
When the drag begins, move the dragging-view out of the scroll view (as a subview) and into the mutual superview of both scroll views.
When the drag ends, move the dragging-view out of the superview and into the new scroll view.
You'll probably have to be careful with coordinate systems, using things like [UIView convertPoint:toView:] to convert between the views' different perspectives when moving things around.

Resources