0

enter image description here

With the image above, I would like to know/detect if the UIView 3 has reached the top of the UIScrollView.

What I did so far is to get the offSet of the UIView within the UIScrollView then check if it's less than or equal to 0 (zero).

let offsetY = scrollView.convert(myView.frame, to: nil).origin.y
if offsetY <= 0 {
    print("myView is at Top")
}

But the code above is surely wrong! anybody who has an idea?

TIA!

SquareBox
  • 823
  • 1
  • 10
  • 22
  • Possible duplicate of [iPhone - knowing if a UIScrollView reached the top or bottom](https://stackoverflow.com/questions/7706152/iphone-knowing-if-a-uiscrollview-reached-the-top-or-bottom) – Adrian Oct 03 '19 at 02:39
  • I think the other post is to determine if the UIScrollView scrolled to the top or the bottom. What I want is to determine if a view has reached the top of the UIScrollView but doesn't mean that the UIScrollView reached it's bottom. – SquareBox Oct 03 '19 at 02:44

3 Answers3

2

Just convert the top of the scroll view and the top of v3 to the same coordinate system and now you can simply look to see which one is higher.

Let sv be the scroll view and v3 be view 3. Then:

func scrollViewDidScroll(_ sv: UIScrollView) {
    let svtop = sv.frame.origin.y
    let v3top = sv.superview!.convert(v3.bounds.origin, from:v3).y
    if v3top < svtop { print("now") }
}
matt
  • 515,959
  • 87
  • 875
  • 1,141
2

I'm actually not seeing anything wrong with your approach. Since according to the documentation, when view is nil, the method converts to window based coordinates:

Parameters

rect    
A rectangle specified in the local coordinate system (bounds) of the receiver.
view    
The view that is the target of the conversion operation. If view 
is nil, this method instead converts to window base coordinates.
 Otherwise, both view and the receiver must belong to the same 
UIWindow object.
valosip
  • 3,167
  • 1
  • 14
  • 26
1

Another option if you don't want to assume the scroll view has a superview.

func scrollViewDidScroll(_ sv: UIScrollView) {
    // The view we want to check if it's at the top of the scroll view        
    //let viewThatMayBeAtTop = UIView()
    
    // get how far in the scroll view this view is
    let yInScrollViewWithoutScroll = sv.convert(viewThatMayBeAtTop.bounds, from: viewThatMayBeAtTop).minY
    
    // How far we've scrolled down
    let scrolledAmount = sv.adjustedContentInset.top + sv.contentOffset.y

    // If how far we've scrolled is equal or greater than the y position of the view, then it's at the top or higher
    let isScrolledToTopOrHigher = scrolledAmount >= yInScrollViewWithoutScroll
    
    if isScrolledToTopOrHigher {
        print("now")
    }
}
ryanholden8
  • 536
  • 4
  • 13