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:).
Related
In my app I have two table views. Both are same height and width and same cell count.
I want when tableview A Scroll Simultaneously tableview B also scroll.
You can use scrollview delegate scrollViewDidScroll for this purpose. This will do the exact thing you want.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == self.tableA{
self.tableB.setContentOffset(self.tableA.contentOffset, animated: false)
}
else if scrollView == self.tableB{
self.tableA.setContentOffset(self.tableA.contentOffset, animated: false)
}
print("scrollViewDidScroll") // to check whether this function is called while scrolling
}
TRY THIS:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
<your tableView Name>.contentOffset = scrollview.contentOffset
}
As Tableview inherits from ScrollView. Try this.
FOR SWIFT 4:
func scrollViewDidScroll(_ scrollView: UIScrollView)
{
<your tableView Name>.contentOffset = scrollview.contentOffset
}
Instead of using tableview you can use UIPickerView with two components.
If you need code let me know.
I have the header (header : UICollectionReusableView) in my UICollectionView. The header has 3 UIView (UIView1, UIView2, UIView3). When I set collectionLayout.sectionHeadersPinToVisibleBounds = true, the header will in top when I scroll the collection. And I want when the header stick in top of UICollectionView, I will hide UIView1 and UIView2. How can I do that?
UICollectionView is a subclass of UIScrollView. This means that is you assign a delegate to it then this delegate may listen to scrollViewDidScroll(_ scrollView: UIScrollView) method which will be called every time the offset changes in your collection view.
On this event you will need to get all of your header views which I assume you may get by calling visibleSupplementaryViews on your collection view and check its class type.
If the received view is indeed your header you will need to check its frame in comparison to your collection view and see if its position is on top. To do so you may convert frame to your coordinates:
func isHeader(headerView: UIView, onTopOfCollectionView collectionView: UICollectionView) -> Bool {
guard let collectionSuperView = collectionView.superview else {
return false // Collection view is not in view hierarchy. This will most likely never happen
}
let convertedFrame = headerView.convert(headerView.bounds, to: collectionSuperView) // Convert frame of the view to whatever is the superview of collection view
return convertedFrame.origin.y <= collectionView.frame.origin.y // Compare frame origins
}
So I guess the whole thing would be something like:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
collectionView.visibleSupplementaryViews(<#My identifier here#>).forEach { view in
if let header = view as? MyHeaderView {
header.hideSecondaryViews = isHeader(headerView: header, onTopOfCollectionView: collectionView)
}
}
}
I hope this gets you on the right track.
I have an UIView in ScrollView superview. I want this UIView to stick to the top and stays there when users scrolls down.
Note that it should start in the middle of a screen and go up respectively when scrolling down.
I've seen many questions and answers but none of them solved my problem
iOS: Add subview with a fix position on screen
Simple way to change the position of UIView?
My code in scrollViewDidScroll method
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y > anchor.frame.origin.y {
var fixedFrame:CGRect = self.anchor.frame
fixedFrame.origin.y = (self.navigationController?.navigationBar.frame.height)!
self.anchor.frame = fixedFrame
}
}
you can do this by saving a initial offset value of Y for your anchor view, then compare it in the scrollview delegate event.
self.initialOffSet = self.anchor.frame.origin.y
func scrollViewDidScroll(_ scrollView: UIScrollView) {
var newFrame = self.anchor.frame
newFrame.origin.y = max(self.initialOffSet!, scrollView.contentOffset.y)
self.anchor.frame = newFrame
}
Why dont you put that view out of your scrollview?It will stay at the top only even when you will be scrolling your scrollview?
I have a VC that contains a collectionView and a scrollView. I put this code to change current page of pageController by scrolling in scrollView :
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
self.pageController.currentPage = Int(pageNumber)
}
It works nice for scrollView but the problem is when i even scroll in collectionView it declares and causes unwanted changing in pageController!
What should i do?
In addition to the answers posted above, You can make use of the tag property of the view.
Just assign a tag (Int) to your scrollview either in xib or via code.
yourScrollView.tag = 10
And in the scrollview delegate method check for this tag:
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView.tag == 10 {
///Your scrollview was scrolled
} else {
// Collection view was scrolled
}
}
if scrollView == yourScrollView{
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
self.pageController.currentPage = Int(pageNumber)
}
check if the instance running the method is actually your scrollView
First you have to understand bit detail about UICollectionView. The UICollectionView is subclassed from UIScrollView. That's why its getting called for both the scrolling (Scrolling collection view and scrolling scroll view). You can do like this to differentiate what type of scrolling it is,
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView == "Your scrollView outlet name" { // Scroll view
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
self.pageController.currentPage = Int(pageNumber)
} else {
// Collection view
}
}
Thanks.
You need to check the scrollView inside the scrollViewDidEndDecelerating if it is your scroll view or your collection view.
Just add an if scrollView == myScrollView before doing the 2 lines of code you have.
Your code shoudl look like this
func
scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView == myScrollView {
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
self.pageController.currentPage = Int(pageNumber)
}
}
I have a scrollview inside tableview (tableview's header) and I want to call this action when scroll finish:
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
let pageNumber = round(bookScrollView.contentOffset.x / bookScrollView.frame.size.width)
pageControl.currentPage = Int(pageNumber)
print("scroll")
}
when I scroll bookScrollView nothing happen, but when table view scroll this function run.
How I detect when bookScrollView scroll and run function?
thanks
Here, you can define, scrollOfTable, or you can also define TAG property. identify and only scroll when scrollview comes in, not tableview.
You also need to check, if your scrollView is setting delegate
self.vsScrollView.delegate = self
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
if scrollView == scrollOfTable {
}
else if scrollView == scrollOfScrollView {
}
else {
//something else
}
}