swiftscrolluiscrollviewcontentoffset

How to run a function on UiScrollView contentOffset Change?


I want to run a function on "UIScrollView contentOffset.x"(on each scroll) changes, in order to make some graphical changes dynamically according to my task requirement.

let scroll = UIScrollView.init()
scroll.frame = CGRect(x: 10, y: 10, width: 500, height: 100)
scroll.backgroundColor = .white
scroll.contentSize.width = 1000
scroll.contentSize.height = 100
view.addSubview(scroll)

to do that two approaches come into my mind

1) 1st approach (not useable)

like

txtfield.addTarget(self, action: #selector(name_editingchange(_:)), for: UIControlEvents.editingChanged)
"this approach use on textfield "on editingChange""

'addTarget' didn't work on scrollview, so i can't use 'UIControlEvents.editingChanged'

2) 2nd approach "addGestureRecognizer" (useable)

scroll.scrollview.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(onscroll)))

@objc func onscroll(_ pan:UIPanGestureRecognizer){
    print("on change run func given below")
    taskcompleted()
}

there is an issue with the 2nd approach when I use "PanGesture" on scroll view, then scrolling ability of scroll view didn't work to recover scrolling ability, through pan gesture I write some code in its function

@objc func onscroll(_ pan:UIPanGestureRecognizer){  

    UIView.animate(withDuration: 0.3) {
        self.scroll.contentOffset.x = self.scroll.contentOffset.x - pan.translation(in: self.view).x
        pan.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
    }

    taskcompleted()
}

but it doesn't work like the original scrolling feature.

I want to run

1)- taskcompleted() func on "UIScrollView contentOffset.x" Change 2)- at the same time scrolling perfectly

How can I do both?


Solution

  • Use UIScrollViewDelegate and scrollViewDidScroll()

    Simple example:

    class TestViewController: UIViewController, UIScrollViewDelegate {
    
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            print(scrollView.contentOffset)
            // perform actions as desired based on contentOffset
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let scroll = UIScrollView.init()
            scroll.frame = CGRect(x: 10, y: 10, width: 500, height: 100)
            scroll.backgroundColor = .white
            scroll.contentSize.width = 1000
            scroll.contentSize.height = 100
            view.addSubview(scroll)
    
            // assign the delegate here
            scroll.delegate = self
        }
    }