Assign function to UIScrollView when scrolling (Swift) - ios

I have a UIViewController with a UIScrollView I've added in Interface Builder. I want to have scrollView functions so I can detect if it's been scrolled up or down. My scroll view is attached with an IBOutlet called "mainScroll." Here is my code:
var lastContentOffset: CGFloat = 0
#IBOutlet weak var mainScroll: UIScrollView!
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
self.lastContentOffset = mainScroll.contentOffset.y
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (self.lastContentOffset < mainScroll.contentOffset.y) {
// did move up
print("Did Move Up")
} else if (self.lastContentOffset > mainScroll.contentOffset.y) {
// did move down
print("Did Move Down")
} else {
// didn't move
}
}
I've added UIScrollViewDelegate to my class. I have a feeling I'm not using the scrollView delegate callbacks properly. How can I take these functions and assign them to my "mainScroll"?

May be you need this in viewDidLoad
mainScroll.delegate = self

Related

I want to scroll every thing except button in view

I am using scroll view which scrolling everything perfectly but i have button at the top of view for dissmissing view i want it to remain there and do not scroll in swift .
Add first UIScrollView and then UIButton to self.view.
Add button outside scrollview content like overlay.
Try this solution:
class TmpVC: UIViewController, UIScrollViewDelegate {
#IBOutlet var scoll : UIScrollView!
#IBOutlet var btn : UIButton!
var btnPoint : CGPoint!
override func viewDidLoad() {
super.viewDidLoad()
scoll.contentSize = CGSize(width: 320, height: 600)
scoll.delegate = self
btnPoint = btn.frame.origin
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
btn.frame.origin = CGPoint(x: btnPoint.x, y: btnPoint.y + scrollView.contentOffset.y)
}
deinit {
print("deinit Tmpvc")
}
}

Embedding a UIScrollView inside of a UIPageViewController and disabling pageView swiping?

I have a UIView subclass (a graph) embedded inside of a UIScrollview inside of a UIViewController which is one of a UIPageViewControllers pages... I'm trying to disable scrolling of the UIPageViewController so that the user scan scroll to see the far left of the graph without paging back. How can I do this? Is a ScrollView even the correct tool for this job?
class HistoricalHealthDataViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var graphScrollView: UIScrollView!
#IBOutlet weak var hockeyTrackerGraphView: HockeyTrackerGraphView! {
didSet {
self.hockeyTrackerGraphView.graphableObjects = HFRGraphableObjects
}
}
var HFRGraphableObjects: [HockeyTrackerGraphableObject] = []
override func viewDidLoad() {
super.viewDidLoad()
graphScrollView.delegate = self
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if let parentPageViewController = parent as? HistoricalPageViewController {
for gestureRecognizer in parentPageViewController.gestureRecognizers {
print("gestureRecognizer")
gestureRecognizer.isEnabled = false
}
}
}
}
You don't show the code for it, but I'm assuming you implement UIPageViewControllerDataSource protocol and somewhere you have the methods:
func pageViewController(UIPageViewController, viewControllerBefore: UIViewController) -> UIViewController? {
}
func pageViewController(UIPageViewController, viewControllerAfter: UIViewController) -> UIViewController? {
}
If you arrange for those methods to return nil while paging is disabled, the page view won't scroll to a different page.

How to detect scrolling on a WKWebView that shows an AMP (Accelerated Mobile Page)

I have a WKWebView and I need to know when it is scrolled, so I bound its scroll view's delegate to my controller in order to use UIScrollView delegate methods:
self.myWebView.scrollView.delegate = self
...
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Do stuff
...
}
It works well for almost every web pages but when the user does a google search, selects an AMP page and then scrolls up or down, I can't detect that scrolling.
Is there a way to know if an AMP page is scrolled?
I hope this works (its working for me) , storing lastContentOffset's Y position and comparing it with current.
private var lastContentOffset: CGFloat = 0
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (self.lastContentOffset > scrollView.contentOffset.y) {
print("move up")
}
else if (self.lastContentOffset < scrollView.contentOffset.y) {
print("move down")
}
self.lastContentOffset = scrollView.contentOffset.y
}
class ViewController: WKNavigationDelegate, UIScrollViewDelegate
var webView: WKWebView!
override func loadView() {
super.loadView()
webView = WKWebView()
webView.navigationDelegate = self
webView.scrollView.delegate = self
view = webView
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print(scrollView.contentOffset.y)
}

passing tableview offset data to tableview cell using delegate

I don't know why but delegates have always hurt my brain.
I have the delegate like so:
protocol StylistControllerDelegate {
func userInteractsWithTableView(tableViewOffset: CGFloat)
}
It sits inside StylistController and is called when the user scrolls:
class StylistController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate {
var delegate : StylistControllerDelegate?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offset = scrollView.contentOffset.y
self.delegate?.userInteractsWithTableView(tableViewOffset: offset)
}
inside the cell I am attempting to set the CGFloat value to a variable:
class CollectionViewCell: UICollectionViewCell, StylistControllerDelegate {
//var stylistControllerTableViewOffset: CGFloat?
func userInteractsWithTableView(tableViewOffset: CGFloat) {
print(tableViewOffset)
if tableViewOffset > 100 {
collectionView.isScrollEnabled = true
} else {
collectionView.isScrollEnabled = false
}
}
}
I use the offset to enable and disable to ability to scroll of the collectionview INSIDE the cell. Once it gets to a certain value (in this case 100), the ability to scroll is enabled.

Why does WKWebView call scrollviewDidScroll when initialised and how to prevent it?

In a UIViewController, I instantiate a WKWebView and set the view controller as the WKWebiew scrollview's delegate:
class MyViewController: UIViewController, UIScrollViewDelegate {
var webView : WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView = WKWebView(frame: self.view.frame)
view = webView
webView.loadHTMLString("<h1>hello</h1>", baseURL: NSURL(string: "http://www.google.com")!)
webView.scrollView.delegate = self
}
func scrollViewDidScroll(scrollView: UIScrollView) {
println("didScroll")
}
The problem I have is that scrollViewDidScroll is called as soon as the WKWebView is created (ie without the user actually scrolling anything).
Why is that and how can I prevent it ?
Set a bool value to true in scrollViewWillBeginDragging method, which is called only when user scrolls and it is not automatically called by WKWebview
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
scrollByDragging = true
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if !scrollByDragging{
UIView.animate(withDuration: 0.01) {
scrollView.setContentOffset(.zero, animated: true)
}
}
}
If you were to use contentOffset, you would be able to detect when the user scrolls.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y >= 0 {
print("didScroll")
}
}
If your UIScrollView is inside a UINavigationController, contentOffset.y will start at -44, but practically 0 is fine to use.

Resources