Swift 斯威夫特:如何收听scrollViewDidScroll来自另一个类

Swift 斯威夫特:如何收听scrollViewDidScroll来自另一个类,swift,delegates,closures,Swift,Delegates,Closures,我有两门课:Foo和Bar: // Foo protocol FooDelegate { func scrollViewDidScroll(offset: CGFloat) } class Foo: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { var delegate: FooDelegate?

我有两门课:
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
事件。在这种情况下使用
代理是否正确?还是有更好的办法?我来自Javascript世界,在那里我会使用
回调
在每个
scrollViewDidScroll
事件上调用我的函数。
Swift
中使用的
callbacks
是否与Javascript中使用的方式相同?

正如我所说的,您所设置的作为将信息提取出来的解决方案是完全有效的。但让我们看看我可能使用的另外两种可能性

从直接设置委托开始。如果在
scrollViewDidScroll(\uScrollView: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和在演示之前设置闭包的示例

您可以在这里使用自己的代理。您可以直接将scrollView的委托设置为Bar。您还可以为Foo上的闭包创建一个属性,并让Bar设置它。它们都是有效的方法。也许你可以举一个例子。“您可以直接将scrollView的委托设置为Bar。”和2。“您还可以为Foo上的闭包创建一个属性,并让Bar设置为”下面答案中的两个示例感谢您的解释和示例!很高兴这有帮助