Last active
April 4, 2020 00:03
-
-
Save acalism/d53d6c20cee744a4b3d3f3b604852681 to your computer and use it in GitHub Desktop.
Find hostView or hostViewController
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
import UIKit | |
// MARK: - FindHostView | |
protocol FindHostView { | |
associatedtype T | |
var hostView: T? { get } | |
} | |
extension FindHostView where Self: UIView { | |
var hostView: T? { | |
var sv = superview | |
while nil != sv { | |
if let s = sv as? T { | |
return s | |
} | |
sv = sv?.superview | |
} | |
return nil | |
} | |
} | |
// UICollectionViewCell 和 header/footer 都是ReusableView类型 | |
extension UICollectionReusableView: FindHostView { | |
typealias T = UICollectionView | |
} | |
extension UITableViewCell: FindHostView { | |
typealias T = UITableView | |
} | |
extension UITableViewHeaderFooterView: FindHostView { | |
typealias T = UITableView | |
} | |
// MARK: - FindHostViewController | |
protocol FindHostViewController { | |
var hostViewController: UIViewController? { get } | |
} | |
extension UIView: FindHostViewController { | |
var hostViewController: UIViewController? { | |
var r = next | |
while nil != r { | |
if let vc = r as? UIViewController { | |
return vc | |
} | |
r = r?.next | |
} | |
return nil | |
} | |
} | |
// MARK: - forward performAction | |
// UITableViewDelegate 和 UICollectionViewDelegate 都有 performAction 方法, | |
// 此委托方法可用于将 cell / header / footer 上的事件转发到它的 delegate | |
extension UITableView { | |
/// supplement for indexPath(for row: UITableViewCell) | |
func indexPath(for headerFooter: UITableViewHeaderFooterView) -> IndexPath? { | |
let rect = headerFooter.frame | |
for i in 0..<numberOfSections { | |
if rect == rectForHeader(inSection: i) { | |
return IndexPath.init(row: -1, section: i) // 头部用-1 | |
} else if rect == rectForFooter(inSection: i) { | |
return IndexPath.init(row: -2, section: i) // 底部用-2 | |
} | |
} | |
return nil | |
} | |
} | |
extension FindHostView where Self: UICollectionViewCell { | |
func forward(for aSelector: Selector) { | |
if let cv = hostView, let ip = cv.indexPath(for: self) { | |
cv.delegate?.collectionView?(cv, performAction: aSelector, forItemAt: ip, withSender: self) | |
} | |
} | |
} | |
extension FindHostView where Self: UITableViewCell { | |
func forward(for aSelector: Selector) { | |
if let cv = hostView, let ip = cv.indexPath(for: self) { | |
cv.delegate?.tableView?(cv, performAction: aSelector, forRowAt: ip, withSender: self) | |
} | |
} | |
} | |
extension FindHostView where Self: UITableViewHeaderFooterView { | |
func forward(for aSelector: Selector) { | |
if let cv = hostView, let ip = cv.indexPath(for: self) { | |
cv.delegate?.tableView?(cv, performAction: aSelector, forRowAt: ip, withSender: self) | |
} | |
} | |
} | |
//protocol ReusableViewInScrollView { | |
// var reuseIdentifier: String? { get } | |
// func prepareForReuse() | |
//} | |
//extension UICollectionReusableView: ReusableViewInScrollView {} | |
//extension UITableViewCell: ReusableViewInScrollView {} | |
//extension UITableViewHeaderFooterView: ReusableViewInScrollView {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment