Gareth Miller
Gareth Miller

Reputation: 402

scrollViewDidScroll not getting called (I set the delegate!)

Situation: I am creating an imageGallery which is a viewController that I am presenting modally. I have created it all programatically, I haven't touched the storyboard. The viewController has a scrollView that contains ImageViews, which each hold an image. I have set scrollView.isPagingEnabled = true and it works as expected, I can scroll through the images fine.

Issue: I am trying to do some work when the scrollView has scrolled. I have set the delegate (which seems to be the main issue people have had when I searched for an answer) but scrollViewDidScroll never gets called. I'm completely at a loss for what is happening.I've tried quite a lot of different things, but have now run out of ideas

@objc public class ImageGallery: UIViewController, UIScrollViewDelegate {

// MARK:- VARIABLES

/// An array of imageItems
@objc public var galleryItems = [ImageGalleryItem]()

/// The index of the image the gallery should start at
@objc public var startingIndex: NSNumber?

/// The UIImage to display if there is an error
@objc public var errorImage: UIImage?

/// The UIImage to display if the ImageGalleryItem doesn't have an image
@objc public var defaultImage: UIImage?

var scrollView: UIScrollView!

// MARK:- INITS

/// Initialiser for ImageGallery passing an array of ImageGalleryItems
///
/// - Parameter ImageGalleryItems: an array of ImageGalleryItems
@objc public init() {

    self.defaultImage = UIImage(named: "default", in: getResourceBundle(), compatibleWith: nil)!
    self.errorImage = UIImage(named: "error", in: getResourceBundle(), compatibleWith: nil)!
    super.init(nibName:nil, bundle:nil)
}


@objc public required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder);
}


// MARK:- VIEW LIFECYCLES
override public func viewDidLoad() {

    super.viewDidLoad()

    configureScrollView()

    self.scrollView.delegate = self
    configureImageViews()
    configurePresentationDefaults()
}


func configureScrollView() {

    self.scrollView = UIScrollView(frame: view.frame)

    self.scrollView.isPagingEnabled = true
    self.scrollView.contentOffset = CGPoint(x: CGFloat(truncating: startingIndex ?? 0) * UIScreen.main.bounds.width, y: 0)

    let imagesCount = galleryItems.count
        let contentWidth = CGFloat(imagesCount) * UIScreen.main.bounds.width
        self.scrollView.contentSize = CGSize(width: contentWidth, height: UIScreen.main.bounds.height)


    if let toolbar = configureToolBar() {

        view.addSubview(self.scrollView)
        view.addSubview(toolbar)
        view.bringSubviewToFront(toolbar)
    }
}

private func scrollViewDidScroll(_ scrollView: UIScrollView) {
    print("delegate")
}

Update

I was missing an !

private func scrollViewDidScroll(_ scrollView: UIScrollView!) {
    print("delegate")
}

Did the trick.

Upvotes: 3

Views: 3450

Answers (3)

Gareth Miller
Gareth Miller

Reputation: 402

Function signature should not be private to match with delegate implementation:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    print("delegate")
}

Solved the issue.

Upvotes: 0

Yannick Loriot
Yannick Loriot

Reputation: 7136

You issue comes from the private access level keyword with the scrollViewDidScroll: delegate method. The UIScrollViewDelegate is an NSObject and as the method is private it can't see the method and so the delegate method is not called. As you class is public, you need to declare the method with a public access level.

Just try this:

public func scrollViewDidScroll(_ scrollView: UIScrollView) {
    print("delegate")
}

Upvotes: 2

Shehata Gamal
Shehata Gamal

Reputation: 100541

Remove private keyword

func scrollViewDidScroll(_ scrollView: UIScrollView)

Upvotes: 4

Related Questions