Rightpoint/Swiftilities

Add control-containable scroll view subclasses

ZevEisenberg opened this issue · 0 comments

These let you start a touch on a button that's inside a scroll view, and then if you start dragging, it cancels the touch on the button and lets you scroll instead. Without these scroll view subclasses, buttons in scroll views will eat touches that start in them, which prevents scrolling and makes the app feel broken. The UITextInput exception is for cases where you have a text field or a label in a scroll view. If you press and hold there, you want to get the text editing magnifier cursor, instead of canceling the touch in the text input.

import UIKit

// These let you start a touch on a button that's inside a scroll view,
// and then if you start dragging, it cancels the touch on the button
// and lets you scroll instead. Without these scroll view subclasses,
// buttons in scroll views will eat touches that start in them, which
// prevents scrolling and makes the app feel broken.
//
// The UITextInput exception is for cases where you have a text field
// or a label in a scroll view. If you press and hold there, you want
// to get the text editing magnifier cursor, instead of canceling the
// touch in the text input element.

final class ControlContainableScrollView: UIScrollView {

    override func touchesShouldCancel(in view: UIView) -> Bool {
        if view is UIControl && !(view is UITextInput) {
            return true
        }

        return super.touchesShouldCancel(in: view)
    }

}

final class ControlContainableTableView: UITableView {

    override func touchesShouldCancel(in view: UIView) -> Bool {
        if view is UIControl && !(view is UITextInput) {
            return true
        }

        return super.touchesShouldCancel(in: view)
    }

}

final class ControlContainableCollectionView: UICollectionView {

    override func touchesShouldCancel(in view: UIView) -> Bool {
        if view is UIControl && !(view is UITextInput) {
            return true
        }

        return super.touchesShouldCancel(in: view)
    }

}