以编程方式将UIPageViewController的转换样式设置为滚动。

42

我正在使用Xcode 6实现我的应用程序,并使用UIPageViewController。我按照appcoda的教程进行操作,一切正常,但是页面指示器无法正常显示。这是因为我无法将UIPageViewController的转换样式设置为“滚动”。

从图形上看,当我单击PageViewController时,选项卡显示的是视图控制器,而不是像appcoda那样的页面视图控制器(请参见下面的图像):

enter image description here

这是我的截图:

enter image description here

是的,我的自定义类被设置为:UIPageViewController,就像在教程中所示。 enter image description here

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

    self.pageViewController.transitionStyle = UIPageViewControllerTransitionStyle.Scroll

但是构建失败了,告诉我它找不到成员转换样式Could not find member transition style。最后一个奇怪的事情是,如果我只写self.pageViewController.transitionStyle,它会成功构建,但仍然使用Page Curl转换。

有人能帮我吗?我正在使用Swift、Xcode 6,并在iOS 8 SDK上开发。


1
尝试清除自定义类并重新设置。 - Kreiri
已经尝试过了,谢谢。 - sameetandpotatoes
当您清除自定义类时,是默认类UIPageViewController还是UIViewController?如果是后者,则意味着您没有使用正确的故事板对象。 - emily
我上传了一个使用Swift5编写的示例代码,其中包含其他人的信息。 https://github.com/sun5022/UIPageViewController - UdevApp
16个回答

43
问题在于,当您在容器中创建UIPageViewController时,容器首先使用一个UIViewController进行创建,这是您看到选项的控制器。
为了解决这个问题,您需要删除设置自定义UIPageViewController的UIViewController。然后从控件选择器中拖动UIPageViewController并将嵌入segue从容器连接到该控制器,然后您可以设置自定义分页控制器并将转换设置为滚动。

2
就是这样!我来这里回答这个问题,但你已经回答了。 :) 给你点赞。所有其他答案都可行,但根本问题在于这个。 :) - Nuno Gonçalves
2
这是正确的解决方案,应该被接受。 - promacuser
这是真正的答案,其他方法都只是懒人的权宜之计! - Luca Davanzo
你真是个救命恩人。 - CristianMoisei

42
您之所以会收到错误信息,是因为transitionStyle是只读属性。如果您想以编程方式设置页面控制器的过渡样式,那么只能在初始化过程中使用以下方法进行设置:
init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation navigationOrientation: UIPageViewControllerNavigationOrientation, options options: [NSObject : AnyObject]!) { ... }

更多信息请参考文档


@sameetandpotatoes 没关系;如果您在Storyboard中创建页面视图控制器,实际上不需要自己调用此方法。如果您完全以编程方式创建页面视图控制器,则会使用此初始化程序,但由于您正在使用Storyboard,只需按照您已经执行的方式选择转换样式即可。 - Mick MacCallum
7
Interface Builder中有一个专门的UIPageViewController图标。您是否使用它而不是拖出一个UIViewController并将其自定义类更改为UIPageViewController? - rvijay007
1
那就是我的问题:我将一个嵌入到了容器中。我必须删除自动生成的VC和segue,并使用正确的对象重新创建它们。你不能只改变类类型。这很糟糕。 - i_am_jorf
@jeffamaphone 我有同样的问题:它嵌入了一个容器中,我没有任何可以更改过渡样式的地方。 - Claus
1
如果在IB中将其嵌入为“UIPageViewController”,则应该有更改过渡样式的选项。 如果您使用已经嵌入的UIViewController只是设置自定义类,那么该选项不会出现。请删除现有内容,从对象选择器中拖出正确的类,并重新连接嵌入式转换。 - i_am_jorf
显示剩余2条评论

31

Swift 3.0

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

2
我不太舒服做这个...我们不调用init(coder:)初始化器会触发世界末日吗? - Nuno Gonçalves
谢谢,这个解决方案也适用于Swift 5.0。对于那些在nib文件或.storyboard中使用UIPageViewController的人来说,这个解决方案是有效的。 - Amjad Tubasi

17

在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")
    }

1
请查看Marcin Deszczynski的答案。 :) - Nuno Gonçalves
2
这里有一个很好的解决方案,不需要使用Storyboard。简单而直接。 - RegularExpression
2
这是正确的答案。适用于Xcode 9.1和Swift 4。 - Ernie

11

这是我在Swift 2.0中解决这个问题的方法

1.创建一个继承自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);

10

我知道这有点晚,但我刚遇到同样的问题,并意识到这是由于我正在使用一个简单的UIViewController,即使我的自定义视图控制器类继承自UIPageViewController,显然xcode的图形菜单无法识别它。

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


10

Xcode 7.1 & Swift 2

在最新版本的Swift中,所有其他解决方法对我都没有完全有效,特别是因为我的类还继承自UIPageViewControllerDataSource和UIPageViewControllerDelegate。要将PageViewController转换为.Scroll,只需向您的类添加这两种方法:

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)
}

1
我的第一个初始化从未被调用。UIPageViewController在故事板中声明。 - sheetal

10

Swift 5 & 4: 只需将这两个函数放在您的页面视图控制器的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 - Lance Samaria

8

在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) 
     }

}

6
这就是子类化。 - Isaac Overacker
请查看Marcin Deszczynski的答案。 :) - Nuno Gonçalves

5

这对我有用。因为如果我重写了 transitionStyle 的 init 方法,如果你在故事板中将 pageViewController 设置为容器视图,则该方法永远不会被调用。

required init?(coder aDecoder: NSCoder) {

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

实际上正确的答案! - Fattie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接