I want to scroll the UIView when collection view scrolls as shown in below video
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print(scrollView.contentOffset.x)
let contentSize = self.propertyImageCollectionView.contentSize
let xOffSet = (((scrollView.contentOffset.x * self.propertyImageCollectionView.frame.width) / (contentSize.width - self.progressViewWidthConstratint.constant)))
let xValue = xOffSet + ((self.progressViewWidthConstratint.constant * self.progressViewLeadingConstraint.constant) / self.propertyImageCollectionView.frame.width)
print( self.progressViewWidthConstratint.constant)
print( xOffSet)
print(xValue)
if xValue > 0 && xValue < self.propertyImageCollectionView.frame.width - self.progressViewWidthConstratint.constant{
self.progressViewLeadingConstraint.constant = xValue
}
}
The view is not scrolling upto end of screen. It stops scrolling before some points. Where am I lacking in my code. I also tried to use KVO but not succeed. Do you have any alternative approach?
Related
i have a collection view which is used to show comment and i am using a uiview at bottom of the view controller with a height of 0.
when user reach the bottom of content in collection view,as he pull up past content i check in scrollviewdidscroll
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if self.comment.count >= 5 {
let offseety = scrollView.contentOffset.y
let contenthight = scrollView.contentSize.height
if offseety > contenthight - scrollView.frame.size.height + 5 && offseety > 50{
if self.viewheight.constant < 50 {
self.viewheight.constant = scrollView.frame.size.height - contenthight + offseety
if offseety > contenthight - scrollView.frame.size.height + 50{
self.anddiii.isHidden = false
self.anddiii.startAnimating()
self.anothershit.isHidden = false
self.anothershit.text = "Loading more"
}
}}else{
}
}
}
but problem after scrolling end the collection view scrolls back,is there a way to put an ofset bellow last collection cell to show uiview in
Try Below code:
self.collectionView.contentInset = UIEdgeInsetsMake(0,0,55,0)
For example, I have a button that when the user tap on it, it will open a pop up scroll view from the bottom, which has a lengthy vertical content. If the user tried to swipe down when the scroll view content offset is at the top, I want to close the scroll view pop up by animating it flying to the bottom of the screen.
How can I detect that event? I know that I can get the event when scroll view did scroll using scrollViewDidScroll function. But it didn't give me any info of whether the user is scrolling up or down. So I can't check like "when the offset.y is 0 and user is still swiping .down then close the popup". Please help. Thanks.
Try this in scrollViewDidScroll(_ scrollView: UIScrollView) method
let scrollDiff = scrollView.contentOffset.y - self.previousScrollOffset
let absoluteTop: CGFloat = 0;
let absoluteBottom: CGFloat = scrollView.contentSize.height - scrollView.frame.size.height;
let isScrollingDown = scrollDiff > 0 && scrollView.contentOffset.y > absoluteTop
let isScrollingUp = scrollDiff < 0 && scrollView.contentOffset.y < absoluteBottom
self.previousScrollOffset = scrollView.contentOffset.y
and set this as global variable var previousScrollOffset: CGFloat = 0;
you can print and check if this is scolling up or down
hope this will give you the direction
I have a UICollectionViewController and I added two UIViews as subviews. One is the purple UIView and above it is another white UIView, with the blue collection view getting scrolled up behind both.
Below those UIViews, I made the collectionView.contentInset from the top 300 (that's the total size of two UIViews' height). What I'm trying to accomplish is to scroll the collection view along with the two UIViews above. It's almost similar to the solution on this thread (Move a view when scrolling in UITableView), except when I override scrollViewDidScroll, the whole frame gets scrolled up and cells go behind the two Views. All I want is to scroll up the UIViews, and then scroll through the collection views. I feel like this might involve nested scroll views.
This was how I overrode scrollViewDidScroll:
var rect = self.view.frame
rect.origin.y = -scrollView.contentOffset.y - 300
self.view.frame = rect
EDIT: I posted a video that demonstrates what I want to do per iOS Tumblr app: https://youtu.be/elfxtzoiHQo
I have achieved the same requirement through some basic steps as below.
//Declare the view which is going to be added as header view
let requiredView = UIView()
//Add your required view as subview of uicollectionview backgroundView view like as
collectionView.backgroundView = UIView()
collectionView.backgroundView?.addSubview(requiredView)
//After that control the frame of requiredHeaderView in scrollViewDidScroll delegate method like
func scrollViewDidScroll(scrollView: UIScrollView) {
let per:CGFloat = 60 //percentage of required view to move on while moving collection view
let deductValue = CGFloat(per / 100 * requiredView.frame.size.height)
let offset = (-(per/100)) * (scrollView.contentOffset.y)
let value = offset - deductValue
let rect = requiredView.frame
self.requiredView.frame = CGRectMake(rect.origin.x, value, rect.size.width, rect.size.height)
}
It sounds like what you want is a header.
you can specify a class or nib for the header with either of these:
self.collectionView.registerClass(_:, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier:)
registerNib(_:, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: )
you should also specify a reference height if you are using a flow layout: self.flowLayout.headerReferenceHeight = ...
then you can provide the header via your UICollectionViewController in: collectionView(_:, viewForSupplementaryElementOfKind:, at:) by checking for the section header kind.
Here is a decent tutorial on this for reference: https://www.raywenderlich.com/78551/beginning-ios-collection-views-swift-part-2
You have a library CSStickyHeaderFlowLayout
From the ReadMe:
UICollectionView replacement of UITableView. Do even more like Parallax Header, Sticky Section Header. Made for iOS 7.
Try this.
headerViewYConstraint is header view's top y constraint.
Stores the last contact offset.
var lastContentOffset: CGFloat = 0
override func scrollViewDidScroll(scrollView: UIScrollView) {
if scrollView != contentScrollView {
if scrollView.dragging || scrollView.decelerating {
let newOffset = scrollView.contentOffset.y
let headerViewHeight = headerView.frame.width
if headerViewHeight > 0 && scrollView.contentSize.height > view.frame.height + headerViewHeight{
var topOffset = newOffset == 0 ? 0.0 : (headerViewYConstraint.constant + lastContentOffset - newOffset)
topOffset = min(0, max(topOffset, -headerViewHeight))
if headerViewYConstraint.constant > topOffset || newOffset < headerViewHeight || lastDirectionalContentOffset - newOffset > cellHeight(){
headerViewYConstraint.constant = topOffset
}
} else {
headerViewYConstraint.constant = 0
}
lastContentOffset = newOffset
}
}
}
I have a ViewController, which has a tableView, and has two views on top of the table view. I need to collapse a view (outlined in red in the image), when the user scrolls up, and move another view (orange button), up with the table. I'm planning on using the scrollViewDidScroll delegate method to detect the offset of the table, and handle the collapsing with that.
How do I go about implementing this?
//Custom delegate method, which returns offset of scrollViewDidScroll
func didScrollScrollView(offset: CGFloat){
print(offset)
//I have the offset, which is -30 on load. How do I implement collapsing of the view highlighted in red?
}
you need to access the frame of the view or better its heightConstraint.
If you have a reference to the heightConstrain you can do:
var previousOffset: CGFloat = -30
func didScrollScrollView(offset: CGFloat){
let diff = previousOffset - offset
previousOffset = offset
var newHeight = heightConstraint.constant + diff
if newHeight < 0 {
newHeight = 0
} else if newHeight > 60 { // or whatever
newHeight = 60
}
heightConstraint.constant = newHeight
}
If you don't use Autolayout you need to update the frames manualy.
Also set clipsSubviews=true (clippedToBounds) in interface builder or in code
I have two UIScrollViews with vertical scroll: foreground and background. The user can only interact with the former; the latter is moved programmatically. How can I make it so that when the user scrolls the foreground, the background scrolls at a proportional rate of ΒΌ? For example, for every 4px that foreground scrolls, background will scroll 1px in the same direction.
How can I achieve this relationship in Swift2?
set your self as the scrollView delegate -
self.foregroundScrollView.delegate = self
and use the UIScrollViewDelegate methods:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
self.lastY = scrollView.contentOffset.y;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// Calculate how much distance the scrollView has travelled since last scroll
CGFloat currentY = scrollView.contentOffset.y;
CGFloat difference = currentY - self.lastY;
// Set new contentOffset for your background scrollView
CGPoint currentBackgroundOffset = self.backgroundScrollView.contentOffset;
currentBackgroundOffset.y += difference/4;
self.backgroundScrollView.contentOffset = currentBackgroundOffset;
// Don't forget to update the lastY
self.lastY = currentY;
}
Swift:
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
lastY = scrollView.contentOffset.y
}
func scrollViewDidScroll(scrollView: UIScrollView) {
// Calculate how much distance the scrollView has travelled since last scroll
let currentY = scrollView.contentOffset.y
let difference = currentY - lastY
// Set new contentOffset for your background scrollView
var currentBackgroundOffset = backgroundScrollView.contentOffset
currentBackgroundOffset.y += difference/4
backgroundScrollView.contentOffset = currentBackgroundOffset
// Don't forget to update the lastY
lastY = currentY
}