Swift:如何从另一个类中监听scrollViewDidScroll

时间:2017-04-13 20:18:14

标签: swift delegates closures

我有两个课程:Foo& Bar

// Foo

protocol FooDelegate {
    func scrollViewDidScroll(offset: CGFloat)
}

class Foo: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    var delegate: FooDelegate?         

    // code truncated for brevity

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        delegate?.scrollViewDidScroll(offset: scrollView.contentOffset.x)
    }

}


// Bar

class Bar: UIViewController, FooDelegate {

    // code truncated for brevity

    func scrollViewDidScroll(offset: CGFloat) {
        print(offset)
    }

}

我需要在Foo中收听scrollViewDidScroll的{​​{1}}事件。在这种情况下使用Bar是否正确?还是有更好的方法?我来自Javascript世界,我将使用delegates在每个callback事件上调用我的函数。 scrollViewDidScrollcallbacks的使用方式与Javascript相同吗?

1 个答案:

答案 0 :(得分:1)

正如我所说,你所设置的内容完全有效,可以作为抽象信息的解决方案。但让我们看看我可能会使用的另外两种可能性。

从直接设置委托开始。如果在scrollViewDidScroll(_ scrollView: UIScrollView)中发生的唯一事情是调用您的委托,并且这是您正在使用的唯一UIScrollViewDelegate方法,那么您只能直接设置委托。

class Bar: UIViewController, FooDelegate {

    let foo = Foo()
    func setup() {
        foo.scrollView.delegate = self
    }

}

如果您的对象已经很好地耦合,这是一个很好的方法。虽然我在您的示例中看到您正在使用UICollectionView,但这可能不是您使用的唯一委托方法。所以让我们看一下闭包。

class Foo: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    var scrollOffSetClosure: ((offset: CGFloat) -> Void)?

    // code truncated for brevity

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        scrollOffSetClosure(offset: scrollView.contentOffset.x)
    }

}

class Bar: UIViewController, FooDelegate {

    func presentFoo() {
        let foo = Foo()
        foo.scrollOffSetClosure = { offset in
            // do something with offset
        }

        present(foo, animated: true, completion: nil)
    }

}

您可以随时设置属性,但我只是使用了呈现下一个viewController并在演示之前设置闭包的示例。