UIScrollView 嵌套在 UIPageViewController 幻灯片中

UIScrollView nested within UIPageViewController slide

我有一个非常标准的 UIPageViewController,可以加载 3 个单独的 UIViewController 来滑动。

其中一个 UIViewController 需要一个在不触发 UIPageViewController 的手势识别器的情况下仍能正常工作的 UIScrollView。

如果触摸是在 UIScrollView 开始的,我如何才能将手势限制在 UIScrollView 上,这样它就不会触发转换?

这是设置图:

UIPageViewController 来源:

class MyPageViewController: UIPageViewController
{
    fileprivate lazy var pages: [UIViewController] = {
        return [
            self.getViewController(withIdentifier: "MyPage1"),
            self.getViewController(withIdentifier: "MyPage2"),
            self.getViewController(withIdentifier: "MyPage3"),
        ]
    }()

    fileprivate func getViewController(withIdentifier identifier: String) -> UIViewController
    {
        return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: identifier)
    }

    var imageView: UIImageView?
    var backgroundVideo : VideoBackground!

    override func viewDidLoad()
    {
        super.viewDidLoad()
        self.dataSource = self
        self.delegate   = self as? UIPageViewControllerDelegate

        if let firstVC = pages.first
        {
            setViewControllers([firstVC], direction: .forward, animated: true, completion: nil)
        }
    }

}

extension MyPageViewController: UIPageViewControllerDataSource
{
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

        guard let viewControllerIndex = pages.index(of: viewController) else { return nil }

        let previousIndex = viewControllerIndex - 1

        guard previousIndex >= 0 else { return nil        }

        guard pages.count > previousIndex else { return nil        }

        return pages[previousIndex]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
    {
        guard let viewControllerIndex = pages.index(of: viewController) else { return nil }
        let nextIndex = viewControllerIndex + 1
        guard nextIndex < pages.count else { return nil        }
        guard pages.count > nextIndex else { return nil         }
        return pages[nextIndex]
    }

    private func setupPageControl() {
        let appearance = UIPageControl.appearance()
        appearance.pageIndicatorTintColor = UIColor.black
        appearance.currentPageIndicatorTintColor = UIColor.white
        appearance.backgroundColor = UIColor.clear
        appearance.isOpaque = false
    }

    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        setupPageControl()
        return self.pages.count
    }

    func presentationIndex(for pageViewController: UIPageViewController) -> Int {
        return 0
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        for view in self.view.subviews {
            if view is UIScrollView {
                view.frame = UIScreen.main.bounds
            } else if view is UIPageControl {
                view.backgroundColor = UIColor.clear
            }
        }
    }

}

extension MyPageViewController: UIPageViewControllerDelegate {}

如果 scrollView 的标准属性(例如延迟页面控制器中的触摸)不起作用,但我认为它们应该起作用,scrollViewscrollView 中通常可以正常工作,您可以始终覆盖 hitTest 方法并使用它来决定哪个 scrollViews 应该接收触摸。只需检查 CGPoint 是否在您的内部滚动视图中,如果是,则 return 那个滚动视图,否则,return 您的超级视图。

这是一个 Storyboard 示例,应该 运行 无需对您发布的代码进行任何编辑(将 Main.storyboard 的源代码替换为以下内容)。

第一个 VC 有一个滚动视图,其中包含一个带有 6 个标签的堆栈视图。堆栈视图是垂直的 Spacing = 160 所以你应该有足够的垂直滚动,它的宽度设置为滚动视图的宽度 + 120,所以你也会得到水平滚动。

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="bGW-rc-7aL">
    <device id="retina4_7" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14824"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--My Page View Controller-->
        <scene sceneID="bIF-VX-tZJ">
            <objects>
                <pageViewController autoresizesArchivedViewToFullSize="NO" transitionStyle="scroll" navigationOrientation="horizontal" spineLocation="none" id="bGW-rc-7aL" customClass="MyPageViewController" customModule="X11SwiftScratch" customModuleProvider="target" sceneMemberID="viewController"/>
                <placeholder placeholderIdentifier="IBFirstResponder" id="Bbm-jJ-ZTN" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="141" y="154"/>
        </scene>
        <!--View Controller-->
        <scene sceneID="aDQ-BH-6ga">
            <objects>
                <viewController storyboardIdentifier="MyPage1" id="0X7-Tt-JCc" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="ORv-uN-p9a">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uhG-aG-m6P">
                                <rect key="frame" x="20" y="20" width="335" height="607"/>
                                <subviews>
                                    <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="160" translatesAutoresizingMaskIntoConstraints="NO" id="oBC-6H-LIT">
                                        <rect key="frame" x="16" y="16" width="455" height="923"/>
                                        <subviews>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="Label 1 of 6 (Left Aligned)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wdR-VH-nME">
                                                <rect key="frame" x="0.0" y="0.0" width="455" height="20.5"/>
                                                <color key="backgroundColor" red="0.45138680930000002" green="0.99309605359999997" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="Label 2 of 6" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4e4-gU-jmU">
                                                <rect key="frame" x="0.0" y="180.5" width="455" height="20.5"/>
                                                <color key="backgroundColor" red="0.45138680930000002" green="0.99309605359999997" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="Label 3 of 6" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RwZ-xg-eTU">
                                                <rect key="frame" x="0.0" y="361" width="455" height="20.5"/>
                                                <color key="backgroundColor" red="0.45138680930000002" green="0.99309605359999997" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="Label 4 of 6" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pCZ-C2-chu">
                                                <rect key="frame" x="0.0" y="541.5" width="455" height="20.5"/>
                                                <color key="backgroundColor" red="0.45138680930000002" green="0.99309605359999997" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="Label 5 of 6" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Eio-bZ-5G0">
                                                <rect key="frame" x="0.0" y="722" width="455" height="20.5"/>
                                                <color key="backgroundColor" red="0.45138680930000002" green="0.99309605359999997" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1000" text="Label 6 of 6 (Right Aligned)" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="r8L-JP-uyd">
                                                <rect key="frame" x="0.0" y="902.5" width="455" height="20.5"/>
                                                <color key="backgroundColor" red="0.45138680930000002" green="0.99309605359999997" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
                                                <nil key="textColor"/>
                                                <nil key="highlightedColor"/>
                                            </label>
                                        </subviews>
                                    </stackView>
                                </subviews>
                                <color key="backgroundColor" systemColor="systemPinkColor" red="1" green="0.17647058823529413" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                <constraints>
                                    <constraint firstItem="A0Z-27-E6L" firstAttribute="trailing" secondItem="oBC-6H-LIT" secondAttribute="trailing" constant="16" id="7BS-Ej-D46"/>
                                    <constraint firstItem="A0Z-27-E6L" firstAttribute="bottom" secondItem="oBC-6H-LIT" secondAttribute="bottom" constant="16" id="7bn-Ov-tgf"/>
                                    <constraint firstItem="oBC-6H-LIT" firstAttribute="leading" secondItem="A0Z-27-E6L" secondAttribute="leading" constant="16" id="GCP-KY-b7Z"/>
                                    <constraint firstItem="oBC-6H-LIT" firstAttribute="top" secondItem="A0Z-27-E6L" secondAttribute="top" constant="16" id="QuF-Rm-AkK"/>
                                    <constraint firstItem="oBC-6H-LIT" firstAttribute="width" secondItem="uhG-aG-m6P" secondAttribute="width" constant="120" id="anG-6u-Yca"/>
                                </constraints>
                                <viewLayoutGuide key="contentLayoutGuide" id="A0Z-27-E6L"/>
                                <viewLayoutGuide key="frameLayoutGuide" id="BCl-PX-Sdc"/>
                            </scrollView>
                        </subviews>
                        <color key="backgroundColor" red="0.0" green="0.97680455450000003" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="uhG-aG-m6P" firstAttribute="leading" secondItem="EcH-SV-2jG" secondAttribute="leading" constant="20" id="01z-qf-UXc"/>
                            <constraint firstItem="EcH-SV-2jG" firstAttribute="trailing" secondItem="uhG-aG-m6P" secondAttribute="trailing" constant="20" id="3dg-7y-1df"/>
                            <constraint firstItem="uhG-aG-m6P" firstAttribute="top" secondItem="EcH-SV-2jG" secondAttribute="top" constant="20" id="Ag3-kQ-VZi"/>
                            <constraint firstItem="EcH-SV-2jG" firstAttribute="bottom" secondItem="uhG-aG-m6P" secondAttribute="bottom" constant="40" id="Kv7-a8-Cbw"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="EcH-SV-2jG"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="xno-2J-adv" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="-505" y="839"/>
        </scene>
        <!--View Controller-->
        <scene sceneID="eCj-2x-uVh">
            <objects>
                <viewController storyboardIdentifier="MyPage2" id="ds7-6v-s81" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="LOr-ii-ZPH">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MyPage2" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UGr-eF-8Ji">
                                <rect key="frame" x="106.5" y="309.5" width="162" height="48"/>
                                <fontDescription key="fontDescription" type="system" pointSize="40"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                        </subviews>
                        <color key="backgroundColor" red="0.46202266219999999" green="0.83828371759999998" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="UGr-eF-8Ji" firstAttribute="centerY" secondItem="LOr-ii-ZPH" secondAttribute="centerY" id="D1t-8l-i7e"/>
                            <constraint firstItem="UGr-eF-8Ji" firstAttribute="centerX" secondItem="LOr-ii-ZPH" secondAttribute="centerX" id="E43-KJ-us0"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="Uuj-0T-WQB"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="q5w-TC-x2k" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="140" y="839"/>
        </scene>
        <!--View Controller-->
        <scene sceneID="Zpi-8N-Mbb">
            <objects>
                <viewController storyboardIdentifier="MyPage3" id="TR7-PG-Lwi" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="ivN-Bt-RDV">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MyPage3" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qNc-nl-0lY">
                                <rect key="frame" x="106" y="309.5" width="163" height="48"/>
                                <fontDescription key="fontDescription" type="system" pointSize="40"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                        </subviews>
                        <color key="backgroundColor" systemColor="systemYellowColor" red="1" green="0.80000000000000004" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="qNc-nl-0lY" firstAttribute="centerX" secondItem="ivN-Bt-RDV" secondAttribute="centerX" id="UvZ-bd-OYw"/>
                            <constraint firstItem="qNc-nl-0lY" firstAttribute="centerY" secondItem="ivN-Bt-RDV" secondAttribute="centerY" id="wGO-1o-zJs"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="ekN-ct-m1b"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="ahl-iN-Pfs" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="798" y="839"/>
        </scene>
    </scenes>
</document>