簡體   English   中英

當我觸摸超出其超級視圖在 iOS 中的位置時,UI 表視圖沒有響應,UI Kit poroject

[英]UI table view is not responsive when I touch beyond its superview's position in iOS, UI Kit poroject

上下文:在iOS UIKit項目中,用swift寫的

假設我有一個超級視圖 - 帶框架的“A”(0、0、320、200)

我有一個子視圖說 'B' 和框架 (0, 0, 320, 600)

並且視圖“B”作為子視圖添加到視圖“A”

現在子視圖“B”中有一個表視圖

面臨的問題

我的子視圖 B 中的 tablew 視圖僅在其超級視圖位置之前響應,即其可滾動和 didSelectRowAt 僅在其超級視圖框架的框架 (0, 0, 320, 200) 內被調用

當我點擊該框架之外的任何行時,沒有響應,有人可以幫我解決這個有線問題,在此先感謝。

處理此問題的最佳方法可能是重寫hitTest方法以返回目標視圖。 像這樣:

class OverridingHitTestView: UIView {
    
    var forwardTo: UIView?
    
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let originalResult = super.hitTest(point, with: event)
        if let forwardTo, originalResult == self {
            return forwardTo.hitTest(point, with: event)
        } else {
            return originalResult
        }
    }
    
}

OverridingHitTestView會將事件發送到您設置forwardTo視圖。 在您的情況下,它應該是您的子視圖的表視圖。

您的OverridingHitTestView必須放置在您的表格視圖下方,並且它需要足夠大以包含您希望處理的所有區域。

我創建了一個簡單的代碼示例,只是為了測試運行它。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let container = OverridingHitTestView(frame: view.bounds)
        view.addSubview(container)
        
        let smallView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 400.0, height: 300.0))
        smallView.backgroundColor = UIColor.green
        container.addSubview(smallView)
        
        let largeView = UIStackView(frame: CGRect(x: 0.0, y: 0.0, width: 400.0, height: 600.0))
        largeView.axis = .vertical
        largeView.distribution = .fillEqually
        (0..<10).forEach { index in
            let button = UIButton(frame: CGRect(x: 0.0, y: 0.0, width: 400.0, height: 60.0))
            button.setTitle("Button \(index+1)", for: .normal)
            button.addTarget(self, action: #selector(onButtonPressed), for: .touchUpInside)
            button.setTitleColor(.black, for: .normal)
            largeView.addArrangedSubview(button)
        }
        
        container.forwardTo = largeView
        
        smallView.addSubview(largeView)
    }

    @objc private func onButtonPressed(_ sender: UIButton) {
        print("Pressed button \(sender.titleLabel?.text ?? "[NA]")")
    }
}

class OverridingHitTestView: UIView {
    
    var forwardTo: UIView?
    
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let originalResult = super.hitTest(point, with: event)
        if let forwardTo, originalResult == self {
            return forwardTo.hitTest(point, with: event)
        } else {
            return originalResult
        }
    }
    
}

深入了解命中測試:

let originalResult = super.hitTest(point, with: event)
if let forwardTo, originalResult == self {
    return forwardTo.hitTest(point, with: event)
} else {
    return originalResult
}

這個想法是我們檢查視圖最初會報告什么。 如果它會報告self ,我們會將調用轉發給我們的目標視圖。 原因是如果用戶確實在該視圖中按下,則會返回self 而且它沒有在這個視圖上按下一些子視圖。 這允許其他元素(例如按鈕)在此視圖中仍然正常工作(並非所有事件都轉發到目標視圖)。

如果不能解決您的問題,我希望這能讓您走上正確的道路。 您仍然可以使用相同的方法,但改變條件,例如在窗口或其他任何地方尋找觸摸位置。 關鍵是您只需要在hitTest上返回正確的視圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM