How to prevent a child view to zoom inside scrollview - ios

I have a scroll view and inside the scrollview I am having a content view with few subview inside this content view. My requirement is to zoom the content view but not the subview of content view.
Can anyone faced this before, or did the same. Any help would be appreciated.
Thanks in advance.

Scroll view just apply transform to contentView. This transform applied to all children in contentView. So you can apply inverted transform to children to negate parent transform.
func scrollViewDidZoom(_ scrollView: UIScrollView) {
guard let content = viewForZooming(in: scrollView) else {
return
}
let t = content.transform.inverted()
for v in content.subviews {
v.transform = t
}
}

Related

how to check if UIScrollView content doesn't need to use scroll

My problem is I need to change the label text color below my scroll view if the content of my scroll view is not all visible.
For example: I have a label colored red, if all the content of the scroll view can be seen on the screen(not using scroll at all), and the label colored blue if all the content inside of my scroll view is not visible. how to do it programmatically?
NOTE: I have a contentView -> scrollView (programmatically) -> stackView (programmatically).
(stackview inside scrollview and scrollview inside contentview. and a label below the content view)
Thanks.
1: Get the height of the content view of scrollView
let totalHeight = scrollView.contentSize.height
2: In viewDidLoad check:
if totalHeight > scrollView.frame.size.height {
// can scroll more
} else {
// full content visible
}
3: once user starts scrolling, you can call:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) {
//reached to bottom
} else {
// can scroll more
}
}
This solution worked for me, with the difference that I placed it in the viewDidAppear
if scrollView.contentSize.height > scrollView.visibleSize.height {
// can scroll more
} else {
// full content visible
}

Implement twitter Profile like view with parallax scroll

I want to implement the following sort of view where the view can be completely scrolled and houses 2 different scrollview (Main and the secondary) with infinite scrollable content. This represents the exact thing I want.
The red view is superview - should scroll vertically
The green view is of the height of the current view and is just static. That doesnt scroll
The blue view is the horizontal scrollview where for each label there is a yellow vertically scrolling infinity collection view
the labels scroll as in the given video. under each label there is the collection view I mentioned in point 3
The blue box is the scroll view and I want the scrolling to happen horizontally in a parallax way such as this.
I am able to implement the above parallax in the correct fashion but each title contains their own collectionview. When I implement this I am not able to have an infinite scroll. Below is the code for that :
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == containerScrollView {
for i in 0..<shotsData.count {
let label = scrollView.viewWithTag(i + tagValueL) as! UILabel
let view = scrollView.viewWithTag(i + tagValueV) as! ShotsMediaView
let scrollContentOffset = scrollView.contentOffset.x + scrollView.frame.width
let viewOffset = (view.center.x - scrollView.bounds.width/4) - scrollContentOffset
label.center.x = scrollContentOffset - ((scrollView.bounds.width/4 - viewOffset)/2)
}
}
}
How can I exactly achieve the same behavior with an infinite scroll vertically? I want each of these titles to have collectionview that have the dynamic height each.
I did a crude implementation of this.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == colorsCollectionView {
let newContentOffSetX = scrollView.contentOffset.x
let distance = contentOffSetX + newContentOffSetX
// Scroll the text collection view proportinately
let titleScrollDistance = (distance/colorsCollectionView.frame.width * 75.0)
titlesCollectionView.contentOffset = CGPoint(x: titleScrollDistance, y: titlesCollectionView.contentOffset.y)
contentOffSetX = newContentOffSetX
}
}
contentOffSetX is a property of the class(ViewController) that I use to keep track of the scrolling distance of the bottom collection view. Initially that is set to 0. When the user scrolls the collection view at the bottom, the above delegate method is called. Then I use the contentOffSet to get the distance that was scrolled along the X-axis. I map that to the width of the title labels(hardcoded as 75.0) to calculate the distance that collection has to be scrolled. Hope this can be refined to serve your purpose, but I am sure that there are better methods out there :)

Move SubView of ChildViewController using scrollViewDidScroll

I am using a viewController to handle two ChildViewControllers, each containing a UITableView. Would it be possible to set the the position y of a SubView of viewController (e.g. a UILabel) depending on the scrollView.contentOffset of the current ChildViewController?
It works fine with its own subviews already,..
func scrollViewDidScroll(_ scrollView: UIScrollView) {
self.testConstt.constant = scrollView.contentOffset.y
}
Thanks for helping!
Just observe the correct scroll view using a conditional statement. I assume the scroll views of the children are table views, so you may do something like this:
let tableViewA = UITableView(...)
let tableViewB = UITableView(...)
let someScrollView = UIScrollView()
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == tableViewA {
// observe a specific table view's scroll view and do something
} else if scrollView == someScrollView {
// observe a specific scroll view and do something
}
}
Remember, UITableView is a subclass of UIScrollView so they can be treated the same in scrollViewDidScroll(_ scrollView:).

Scroll Collection view to the top

I have a following collection view. When the user scrolls the view up, I want the collection view to go all the way up. Similarly, when it is scrolled down, I want it to come back to its original position.
I have a uiview and imageView above the collectionview.
Now, If this was a tableview, I would have used header. How do i achieve this behavious. I am out of Ideas.
Thanks in advance
UICollectionView is the sub-class of UIScrollView so you can achieve what you want is just by the scrollview delegate method and the constraints of your UIView and UIImageView upon the UICollectionView.
Here I am going to give you one example to achieve this with scrollview delegate.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == collectionView{
if scrollView.contentOffset.y == 0{
UIView.animate(withDuration: 0.5) { () -> Void in
self.constTopTagHeight.constant = 175 // Your UIView and imageview constraints adjust.
self.view.layoutIfNeeded()
}
}
else{
UIView.animate(withDuration: 0.5) { () -> Void in
self.constTopTagHeight.constant = 0 // Your UIView and imageview constraints adjust.
self.view.layoutIfNeeded()
}
}
}
}
Hope this help you.

Detect when label appears on screen in SWIFT

I have a scroll view with several elements (textview, label, image view...), I need to display an uiview when my label appears on the screen when I'm scrolling.
How can I do ?
Make sure your view controller is the scroll view delegate. Implement the scrollViewDidScroll method, and check whether the scroll view's frame, offset by the contentOffset, overlaps the label's frame.
func scrollViewDidScroll(scrollView: UIScrollView) {
let offset = self.scrollView.contentOffset
let onScreen = CGRectOffset(self.scrollView.frame, offset.x, offset.y)
if CGRectIntersectsRect(onScreen, self.label.frame) {
NSLog("Overlap")
}
}
If you want to detect when the label is fully on the screen, use CGRectContainsRect instead of CGRectIntersectsRect.

Resources