Created
December 1, 2018 07:43
-
-
Save AmatsuZero/6258367894ee2478afeb492eba46976e to your computer and use it in GitHub Desktop.
无限滚动TableView
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// InfiniteTableView.swift | |
// EShopHelper | |
// | |
// Created by Jiang,Zhenhua on 2018/12/1. | |
// Copyright © 2018 Daubert. All rights reserved. | |
// | |
import UIKit | |
class InfiniteTableView: UITableView { | |
class Interceptor: NSObject, UITableViewDataSource { | |
weak var receiver: UITableViewDataSource! | |
weak var middleman: UITableView? | |
private var actualRows = 0 | |
override func forwardingTarget(for aSelector: Selector!) -> Any? { | |
if let middleman = middleman, middleman.responds(to: aSelector) { | |
return middleman | |
} | |
if let receiver = receiver, receiver.responds(to: aSelector) { | |
return receiver | |
} | |
return super.forwardingTarget(for: aSelector) | |
} | |
override func responds(to aSelector: Selector!) -> Bool { | |
if let middleman = middleman, middleman.responds(to: aSelector) { | |
return true | |
} | |
if let receiver = receiver, receiver.responds(to: aSelector) { | |
return true | |
} | |
return super.responds(to: aSelector) | |
} | |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
actualRows = receiver.tableView(tableView, numberOfRowsInSection: section) | |
return actualRows * 3 | |
} | |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let actualIndexPath = IndexPath(row: indexPath.row % actualRows, section: indexPath.section) | |
return receiver.tableView(tableView, cellForRowAt: actualIndexPath) | |
} | |
} | |
private lazy var dataSourceInterceptor: Interceptor = { | |
let interceptor = Interceptor() | |
interceptor.middleman = self | |
return interceptor | |
}() | |
override func layoutSubviews() { | |
resetContentOffsetIfNeeded() | |
super.layoutSubviews() | |
} | |
private func resetContentOffsetIfNeeded() { | |
var contentOffset = self.contentOffset | |
if contentOffset.y < 0 {// scroll over top | |
contentOffset.y = contentSize.height / 3 | |
} else if contentOffset.y >= contentSize.height - bounds.size.height { // scroll over bottom | |
contentOffset.y = contentSize.height / 3 - bounds.size.height | |
} | |
self.contentOffset = contentOffset | |
} | |
override var dataSource: UITableViewDataSource? { | |
set(dataSource) { | |
dataSourceInterceptor.receiver = dataSource | |
} | |
get { | |
return dataSourceInterceptor | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment