UIPageViewController:翻页时如何防止页面正面的内容部分透到背面

问题描述 投票:0回答:1

我有一个

UIPageViewController
使用transitionStyle
.pageCurl
。我注意到在翻页的时候,翻页的正面在翻页的背面出现了波谷。即使有坚实的背景,即使
isOpaque
对于 viewcontroller 的翻页视图也是如此。

Apple 的 documentation for

isDoubleSided
状态:

如果页面背面没有内容(值为false),则翻页时,页面正面的内容会部分透到背面

有什么办法可以改变这种行为,让页面的背面只显示纯色背景(而不是上面可能出现的任何其他内容)?

uikit uipageviewcontroller
1个回答
0
投票

首先想到的是......使用双面页面视图控制器,并在每个“真实”页面之后插入一个“空白”页面。

快速示例...

我将使用一个“基本”视图控制器来容纳两个子页面视图控制器——一个单面,另一个双面。我们将在该“基本”控制器中创建页面数组,将空白(深灰色)页面插入第二个页面的数组中:

Base controller - 将持有一个页面视图控制器的两个实例作为孩子:

class BaseViewController: UIViewController {
    
    var singleSidedPVC: SamplePageViewController!
    var doubleSidedPVC: SamplePageViewController!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // views to hold the page view controllers
        let ssContainer = UIView()
        ssContainer.backgroundColor = .gray
        
        let dsContainer = UIView()
        dsContainer.backgroundColor = .gray
        
        [ssContainer, dsContainer].forEach { v in
            v.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(v)
        }
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            
            ssContainer.topAnchor.constraint(equalTo: g.topAnchor, constant: 60.0),
            ssContainer.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            ssContainer.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
            ssContainer.heightAnchor.constraint(equalTo: ssContainer.widthAnchor, multiplier: 0.75),
            
            dsContainer.topAnchor.constraint(equalTo: ssContainer.bottomAnchor, constant: 60.0),
            dsContainer.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            dsContainer.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
            dsContainer.heightAnchor.constraint(equalTo: dsContainer.widthAnchor, multiplier: 0.75),
            
        ])

        // single-sided - back of page shows through
        singleSidedPVC = SamplePageViewController(transitionStyle: .pageCurl, navigationOrientation: .horizontal)
        singleSidedPVC.isDoubleSided = false
        addChild(singleSidedPVC)
        singleSidedPVC.view.translatesAutoresizingMaskIntoConstraints = false
        ssContainer.addSubview(singleSidedPVC.view)
        
        NSLayoutConstraint.activate([
            
            singleSidedPVC.view.topAnchor.constraint(equalTo: ssContainer.topAnchor),
            singleSidedPVC.view.leadingAnchor.constraint(equalTo: ssContainer.leadingAnchor),
            singleSidedPVC.view.trailingAnchor.constraint(equalTo: ssContainer.trailingAnchor),
            singleSidedPVC.view.bottomAnchor.constraint(equalTo: ssContainer.bottomAnchor),
            
        ])
        
        singleSidedPVC.didMove(toParent: self)

        // double-sided - we'll insert a blank page between every page
        doubleSidedPVC = SamplePageViewController(transitionStyle: .pageCurl, navigationOrientation: .horizontal)
        doubleSidedPVC.isDoubleSided = true
        addChild(doubleSidedPVC)
        doubleSidedPVC.view.translatesAutoresizingMaskIntoConstraints = false
        dsContainer.addSubview(doubleSidedPVC.view)
        
        NSLayoutConstraint.activate([
            
            doubleSidedPVC.view.topAnchor.constraint(equalTo: dsContainer.topAnchor),
            doubleSidedPVC.view.leadingAnchor.constraint(equalTo: dsContainer.leadingAnchor),
            doubleSidedPVC.view.trailingAnchor.constraint(equalTo: dsContainer.trailingAnchor),
            doubleSidedPVC.view.bottomAnchor.constraint(equalTo: dsContainer.bottomAnchor),
            
        ])
        
        doubleSidedPVC.didMove(toParent: self)
        

        // let's add pages to each controller
        let colors: [UIColor] = [
            .systemRed,
            .systemGreen,
            .systemBlue,
            .red,
            .green,
            .blue,
        ]

        var pvcControllers: [UIViewController]!
        
        pvcControllers = []
        for i in 0..<colors.count {
            let vc = MyExamplePageViewVC()
            vc.theLabel.text = "Page: \(i)"
            vc.view.backgroundColor = colors[i]
            pvcControllers.append(vc)
        }
        
        singleSidedPVC.pageViewControllers = pvcControllers
        
        pvcControllers = []
        for i in 0..<colors.count {
            let vc = MyExamplePageViewVC()
            vc.theLabel.text = "Page: \(i)"
            vc.view.backgroundColor = colors[i]
            pvcControllers.append(vc)
            
            // for double-sided controller, we're inserting
            //  a "blank" page VC after every "real" page VC
            //  so *that* is what shows on the back of the curl
            let blankVC = UIViewController()
            blankVC.view.backgroundColor = .darkGray
            pvcControllers.append(blankVC)
        }
        
        doubleSidedPVC.pageViewControllers = pvcControllers

    }
    
}

SamplePageViewController - 非常标准:

class SamplePageViewController: UIPageViewController {
    
    // this will be set by the parent controller
    var pageViewControllers: [UIViewController] = [] {
        didSet {
            setViewControllers([pageViewControllers[0]], direction: .forward, animated: false, completion: nil)
        }
    }
    
    override init(transitionStyle style: UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [UIPageViewController.OptionsKey : Any]? = nil) {
        super.init(transitionStyle: style, navigationOrientation: navigationOrientation, options: options)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        dataSource = self
    }
    
}

extension SamplePageViewController: UIPageViewControllerDataSource {
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        
        guard let viewControllerIndex = pageViewControllers.firstIndex(of: viewController) else { return nil }
        
        let previousIndex = viewControllerIndex - 1
        guard previousIndex >= 0 else { return nil }
        
        return pageViewControllers[previousIndex]
    }
    
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        
        guard let viewControllerIndex = pageViewControllers.firstIndex(of: viewController) else { return nil }
        
        let nextIndex = viewControllerIndex + 1
        guard nextIndex < pageViewControllers.count else { return nil }
        
        return pageViewControllers[nextIndex]
    }
    
}

MyExamplePageViewVC - 同样,非常标准......每个页面都会有一个标签来填充大部分框架:

class MyExamplePageViewVC: UIViewController {
    
    let theLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .yellow
        v.textAlignment = .center
        v.font = .systemFont(ofSize: 36.0, weight: .light)
        return v
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .blue
        
        view.addSubview(theLabel)
        NSLayoutConstraint.activate([
            theLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            theLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            theLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.9),
            theLabel.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.9),
        ])
        
    }
    
}

运行时的样子:

© www.soinside.com 2019 - 2024. All rights reserved.