以编程方式将 UIPageViewController 过渡样式设置为滚动

Posted

技术标签:

【中文标题】以编程方式将 UIPageViewController 过渡样式设置为滚动【英文标题】:Programmatically set UIPageViewController Transition Style to Scroll 【发布时间】:2014-07-04 15:26:55 【问题描述】:

我正在使用 Xcode 6 并为我的应用程序实现 UIPageViewController。我关注了appcoda's tutorial,除了页面指示器外,一切正常。这是因为我无法将UIPageViewController 的过渡样式设置为滚动。

以图形方式,当我单击PageViewController 时,该选项卡显示视图控制器而不是像appcoda 那样的页面视图控制器(见下图)

这是我的样子:

是的,我的自定义类设置为:UIPageViewController,就像在教程中一样。

以编程方式,我尝试使用以下方式设置过渡样式:

    self.pageViewController.transitionStyle = UIPageViewControllerTransitionStyle.Scroll

但它构建失败,告诉我它找不到成员转换样式。 我想指出的最后一件奇怪的事情是,如果我只写self.pageViewController.transitionStyle,它会成功构建,但它仍然使用Page Curl 转换。

谁能帮助我?我正在使用 Swift、Xcode 6,并在 ios 8 SDK 上进行开发。

【问题讨论】:

尝试清除自定义类并将其重新设置。 已经试过了,谢谢。 清除自​​定义类时,默认类是UIPageViewController还是UIViewController,如果是后者则说明你没有使用正确的故事板对象。 我用其他人的信息上传了swift5中的示例代码。 github.com/sun5022/UIPageViewController 【参考方案1】:

您收到错误消息,因为 transitionStyle 是只读属性。如果你想通过编程方式设置页面控制器的过渡风格,只能在初始化时使用方法:

init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation navigationOrientation: UIPageViewControllerNavigationOrientation, options options: [NSObject : AnyObject]!)  ... 

the documentation 中的更多信息。

【讨论】:

这似乎可行,但我无法实现它。我到底要把这个放在哪里?在 appcoda 的教程中,我在 ViewController 中使用:self.pageViewController = self.storyboard.instantiateViewControllerWithIdentifier("PageViewController") as UIPageViewController 实例化 UIPageViewController。 (对不起这些基本问题,我正在同时学习Swift和Objective C以及iOS开发) @sameetandpotatoes 没关系;如果您在情节提要中创建页面视图控制器,您实际上不必自己调用此方法。如果您完全以编程方式创建页面视图控制器,您将使用此初始化程序,但由于您使用的是故事板,因此只需按照您已经在做的方式选择过渡样式。 Interface Builder 中专门有一个 UIPageViewController 图标。您是否使用它而不是拖出 UIViewController 并将其自定义类更改为 UIPageViewController? 这是我的问题:我在容器中嵌入了一个。我不得不删除自动生成的 VC 和 segue,并使用正确的对象重新创建它们。您不能只更改课程类型。这是蹩脚的。 如果您将其作为UIPageViewController 嵌入到IB 中,则应该有一个更改过渡样式的选项。如果您采用了已嵌入的UIViewController 并仅设置自定义类,则该选项将不存在。删除你有的,从对象选择器中拖出正确的类,然后重新连接嵌入segue。【参考方案2】:

问题在于,当您在 Container 中创建 UIPageViewController 时,首先使用 UIViewController 创建容器,而这就是您可以看到的控制器。

为了修复它,您必须删除设置自定义 UIPageViewController 的 UIViewController。然后从控件选择器中拖动 UIPageViewController 并将嵌入 segue 从容器连接到该控制器,然后您可以设置自定义分页器控制器以及将转换设置为滚动。

【讨论】:

就是这样!我是来回答这个问题的,但你已经做到了。 :) 为你点赞。所有其他答案都有效,但根本问题是这个。 :) 这是正确的解决方案,应该被接受。 这是真正的答案,其他都是很好的懒惰解决方法! 你是救生员。【参考方案3】:

Swift 3.0

required init?(coder aDecoder: NSCoder) 
    super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)

【讨论】:

我不喜欢这样做......我们不是在触发世界末日而不调用 init(coder:) 初始化程序吗? 谢谢 它也适用于 swift 5.0。此解决方案适用于在 nib 文件或 .storyboard 中使用 UIPageViewController 的人【参考方案4】:

在 ios 8 swift3 中

override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : Any]? = nil) 
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: options)
    

    required init?(coder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

【讨论】:

请查看 Marcin Deszczynski 的回答。 :) 没有情节提要的好解决方案。简单明了。 这是正确的答案。应用于 Xcode 9.1 & Swift 4【参考方案5】:

这就是我在 Swift 2.01 中解决这个问题的方法。创建了一个类,它是类 UIPageViewController 的子类

    import UIKit
    
    class OPageViewController: UIPageViewController 
        
        override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?) 

           // Here i changed the transition style: UIPageViewControllerTransitionStyle.Scroll           
            super.init(transitionStyle: UIPageViewControllerTransitionStyle.Scroll, navigationOrientation: UIPageViewControllerNavigationOrientation.Horizontal, options: options)
        
    
        required init?(coder: NSCoder) 
            fatalError("init(coder:) has not been implemented")
        
    
        override func viewDidLoad() 
            super.viewDidLoad()
        
    
    
    

2.比我刚用过的:D

pageController = OPageViewController()
pageController.dataSource = self
pageController.setViewControllers(NSArray(object: vc) as? [UIViewController], direction: .Forward, animated: true, completion: nil)
pageController.view.frame = CGRectMake(0, container.frame.origin.y, view.frame.size.width, container.frame.size.height);

【讨论】:

【参考方案6】:

我知道这有点晚了,但我刚刚遇到了同样的问题,并意识到它的起源是因为我使用了一个简单的 UIViewController,即使我的自定义视图控制器类继承自 UIPageViewController,显然是 xcode 的图形菜单不认识。

解决方案是在故事板中删除视图控制器并拖动一个 PageViewController 来替换它。这将具有带有滚动选项的图形菜单。

【讨论】:

【参考方案7】:

Xcode 7.1 和 Swift 2

在最新的 Swift 中,所有其他解决方案都不能完全为我工作,尤其是因为我的类也继承自 UIPageViewControllerDataSource 和 UIPageViewControllerDelegate。

要将 PageViewController 转换设置为 .Scroll,只需将以下 2 个方法添加到您的类中:

override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?) 
    super.init(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: options)


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)

【讨论】:

我的第一个 init 永远不会被调用。 UIPageViewController 在故事板中声明【参考方案8】:

斯威夫特 5 和 4: 只需将这 2 个函数放在您的综合浏览量 VC 中的 viewDidLoad() 之前

override init(transitionStyle style: UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [UIPageViewController.OptionsKey : Any]? = nil) 
    super.init(transitionStyle: .pageCurl, navigationOrientation: .horizontal, options: nil)


required init?(coder: NSCoder) 
    fatalError("init(coder:) has not been implemented")

【讨论】:

transitionStyle: .scroll【参考方案9】:

在 Swift 2.0 中以编程方式执行此操作的最简单方法(无需子类化):

class PageViewController: UIPageViewController 

     override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation navigationOrientation: UIPageViewControllerNavigationOrientation, options options: [NSObject : AnyObject]!) 
          super.init(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: options) 
     


【讨论】:

子类化。 请查看 Marcin Deszczynski 的回答。 :)【参考方案10】:

这对我有用。因为如果我覆盖了 transitionStyle 的 init ,如果你在 Storyboard 的容器视图中设置了 pageViewController ,它将永远不会被调用。

required init?(coder aDecoder: NSCoder) 

        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    

【讨论】:

真正正确的答案!【参考方案11】:

Swift 4 以编程方式设置 UIPageViewController 的过渡样式

这直接来自“UIPageViewController.h”第 61-97 行

只需将它放在 UIPageViewController() 类中的 viewDidLoad() 之前

    override init(transitionStyle style: 
UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : Any]? = nil) 
            super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
        
        required init?(coder: NSCoder) 
            fatalError("init(coder:) has not been implemented")
        

【讨论】:

【参考方案12】:

这是 UIPageViewController 的一个已知错误

您可以在this SO question 中阅读原因解释,在this one 中阅读更全面的解释。

我也使用了 AppCoda 教程来掌握 PageViewControllers。另一个 SO 用户实际上写了一个要点,以一种我不必在我自己的项目中更改一行代码的方式为我解决了这个问题。只需将 AVC 放入您的项目并在代码中调用它而不是 UIPageViewController。

Paul de Lange 的AlzheimerViewController。

【讨论】:

【参考方案13】:

swift 3 xcode 8

类 ...: UIPageViewController

override var transitionStyle: UIPageViewControllerTransitionStyle 
    return .scroll


override var navigationOrientation: UIPageViewControllerNavigationOrientation 
    return .horizontal

【讨论】:

【参考方案14】:

以下解决方案均不适用于 Swift 5。 这对我有用,在我的情况下,我需要将视图控制器呈现在具有低不透明度背景的另一个视图控制器之上:

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) 
    super.init(nibName: nil, bundle: nil)

    self.setupView()


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)

    self.setupView()


private func setupView() 
    self.modalTransitionStyle = .crossDissolve
    self.modalPresentationStyle = .overCurrentContext
    self.view.backgroundColor = UIColor.red.withAlphaComponent(0.3)

【讨论】:

【参考方案15】:

斯威夫特 5

class OnboardingController: UIPageViewController 

    override init(transitionStyle style: UIPageViewController.TransitionStyle, navigationOrientation: UIPageViewController.NavigationOrientation, options: [UIPageViewController.OptionsKey : Any]? = nil) 
        super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    

    required init?(coder: NSCoder) 
        super.init(coder: coder)
        print("init(coder:) has not been implemented")
    

    override func viewDidLoad() 
        super.viewDidLoad()
    

【讨论】:

以上是关于以编程方式将 UIPageViewController 过渡样式设置为滚动的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式将按钮添加到导航栏

如何以编程方式将空间添加到任务控制?

以编程方式将“测试版”apk 升级为“生产”

如何以编程方式将 Google Sheet 脚本发布/部署为 API 可执行文件?

如何以编程方式将 selectableItemBackground 添​​加到 ImageButton?

以编程方式将网页 HTM 保存为文本文件