Hier ist eine einfache Arbeits Spielplatz Version in Swift 3, die rein als Beobachter fungiert und nicht nur als Abfangjäger wie die anderen Antworten hier.
Die Unterscheidung ist, dass der ursprüngliche Bildlauf-Delegat alle seine Delegate-Methoden wie normal aufgerufen haben sollte im Gegensatz zu ihnen von einem anderen Delegaten entführt werden.
(Sie können Kopieren/Einfügen dieser in einen Spielplatz und führen Sie es zu testen)
import UIKit
final class ScrollViewObserver: NSObject, UIScrollViewDelegate {
// MARK: - Instantiation
init(scrollView: UIScrollView) {
super.init()
self.scrollView = scrollView
self.originalScrollDelegate = scrollView.delegate
scrollView.delegate = self
}
deinit {
self.remove()
}
// MARK: - API
/// Removes ourselves as an observer, resetting the scroll view's original delegate
func remove() {
self.scrollView?.delegate = self.originalScrollDelegate
}
// MARK: - Private Properties
fileprivate weak var scrollView: UIScrollView?
fileprivate weak var originalScrollDelegate: UIScrollViewDelegate?
// MARK: - Forwarding Delegates
/// Note: we forward all delegate calls here since Swift does not support forwardInvocation: or NSProxy
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Run any custom logic or send any notifications here
print("proxy did scroll")
// Then, forward the call to the original delegate
self.originalScrollDelegate?.scrollViewDidScroll?(scrollView)
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
self.originalScrollDelegate?.scrollViewDidZoom?(scrollView)
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
self.originalScrollDelegate?.scrollViewWillBeginDragging?(scrollView)
}
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
self.originalScrollDelegate?.scrollViewWillEndDragging?(scrollView, withVelocity: velocity, targetContentOffset: targetContentOffset)
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
self.originalScrollDelegate?.scrollViewDidEndDragging?(scrollView, willDecelerate: decelerate)
}
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
self.originalScrollDelegate?.scrollViewWillBeginDecelerating?(scrollView)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
self.originalScrollDelegate?.scrollViewDidEndDecelerating?(scrollView)
}
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
self.originalScrollDelegate?.scrollViewDidEndScrollingAnimation?(scrollView)
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return self.originalScrollDelegate?.viewForZooming?(in: scrollView)
}
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
self.originalScrollDelegate?.scrollViewWillBeginZooming?(scrollView, with: view)
}
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
self.originalScrollDelegate?.scrollViewDidEndZooming?(scrollView, with: view, atScale: scale)
}
func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
return self.originalScrollDelegate?.scrollViewShouldScrollToTop?(scrollView) == true
}
func scrollViewDidScrollToTop(_ scrollView: UIScrollView) {
self.originalScrollDelegate?.scrollViewDidScrollToTop?(scrollView)
}
}
final class TestView: UIView, UIScrollViewDelegate {
let scrollView = UIScrollView()
fileprivate(set) var scrollObserver: ScrollViewObserver?
required init() {
super.init(frame: .zero)
self.scrollView.delegate = self
self.scrollObserver = ScrollViewObserver(scrollView: self.scrollView)
}
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("view's original did scroll delegate method called")
}
}
let testView = TestView()
testView.scrollView.setContentOffset(CGPoint(x: 0, y: 100), animated: true)
testView.scrollObserver?.remove()
print("removed the observer")
testView.scrollView.setContentOffset(CGPoint(x: 0, y: 200), animated: true)
testView.scrollView.setContentOffset(CGPoint(x: 0, y: 300), animated: true)
Dieser druckt
Proxy
Ansicht des ursprünglichen tat scroll Delegatmethode
genannt hat blättern
entfernt den Beobachter
Scroll-Delegat ursprünglich tat Methode Ansicht
Ansicht Original tat scroll Delegatmethode
genannt
Wissen Sie, wie man dieses Problem zu lösen in ObjC und wollen Portierung auf Swift genannt? – e1985
Wenn nicht, versuchen Sie dies mit der Lösung in dieser Antwort http://stackoverflow.com/a/9986842/637641 – e1985
Ich kann nicht eine Swift-Implementierung herausfinden. –