You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FloatingTableView中重写不同类型的delegate属性(仿UITableView实现)

How to Subclass UITableView and Override Delegate to a Custom Protocol

Got it, let's break down how to replicate the pattern UITableView uses with UIScrollView—subclassing UITableView to create FloatingTableView, and overriding the delegate property to use your custom FloatingTableViewDelegate protocol (which inherits from UITableViewDelegate). This relies on Swift's protocol inheritance and property covariance, just like Apple's implementation.

Step 1: Define Your Custom Delegate Protocol

First, create your FloatingTableViewDelegate protocol that inherits from UITableViewDelegate. Mark it with @objc (since UITableViewDelegate is Objective-C-compatible) and use @objc optional for custom methods so implementers can choose whether to use them:

import UIKit

@objc protocol FloatingTableViewDelegate: UITableViewDelegate {
    // Add your custom delegate methods here
    @objc optional func floatingTableViewDidTriggerFloat(_ tableView: FloatingTableView)
    @objc optional func floatingTableView(_ tableView: FloatingTableView, didUpdateFloatState isFloating: Bool)
}

Step 2: Subclass UITableView and Override the Delegate Property

Next, build your FloatingTableView subclass. We'll use a private storage variable for the custom delegate, then override the delegate property to expose the custom protocol type. We also ensure the underlying UITableView delegate points to your custom delegate (since it's compatible with UITableViewDelegate):

class FloatingTableView: UITableView {
    // Private storage to hold our custom delegate
    private weak var _floatingDelegate: FloatingTableViewDelegate?
    
    // Override the delegate property to use our custom protocol type
    override weak var delegate: FloatingTableViewDelegate? {
        get {
            return _floatingDelegate
        }
        set {
            _floatingDelegate = newValue
            // Pass the custom delegate to the superclass's delegate property
            // This works because FloatingTableViewDelegate inherits from UITableViewDelegate
            super.delegate = newValue
        }
    }
    
    // Optional: Add custom logic that triggers your delegate methods
    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        super.scrollViewDidScroll(scrollView)
        
        // Example: Trigger a custom delegate method when the table scrolls past a threshold
        let scrollThreshold = 100.0
        if contentOffset.y > scrollThreshold {
            _floatingDelegate?.floatingTableViewDidTriggerFloat?(self)
        }
    }
}

Step 3: Use Your Custom Table View and Delegate

Now you can use FloatingTableView just like a regular UITableView, with the added benefit of your custom delegate methods:

class ExampleViewController: UIViewController, FloatingTableViewDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let floatingTable = FloatingTableView(frame: view.bounds)
        floatingTable.delegate = self
        floatingTable.dataSource = self // Don't forget your data source!
        view.addSubview(floatingTable)
        
        // Configure table view (register cells, etc.)
        floatingTable.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    }
    
    // MARK: - UITableViewDelegate
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Selected row \(indexPath.row)")
    }
    
    // MARK: - FloatingTableViewDelegate
    func floatingTableViewDidTriggerFloat(_ tableView: FloatingTableView) {
        print("Table view crossed the scroll threshold and is now 'floating'!")
    }
}

// Add UITableViewDataSource conformance for completeness
extension ExampleViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 20
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        cell.textLabel?.text = "Row \(indexPath.row)"
        return cell
    }
}

Troubleshooting Common Issues

  • Compile error about covariant types: Ensure your FloatingTableViewDelegate explicitly inherits from UITableViewDelegate and is marked with @objc. Swift allows property covariance only for Objective-C-compatible protocols.
  • Custom delegate methods not firing: Double-check that custom methods are marked with @objc optional, the delegate property is set correctly, and your view controller conforms to FloatingTableViewDelegate.
  • System UITableViewDelegate methods not working: Since we set super.delegate = newValue, standard delegate methods should work as expected. If they don't, verify your delegate implements those methods and you didn't override them in FloatingTableView without calling super.

内容的提问来源于stack exchange,提问作者Syed Qamar Abbas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:24:39