我正在尝试从故事板中特定配置UIPageViewController:
TutorialPageViewController.h
#import <UIKit/UIKit.h>
@interface TutorialPageViewController : UIPageViewController <UIPageViewControllerDelegate, UIPageViewControllerDataSource>
@end
TutorialPageViewController.m
#import "TutorialPageViewController.h"
@interface TutorialPageViewController ()
@property (assign, nonatomic) NSInteger index;
@end
@implementation TutorialPageViewController
{
NSArray *myViewControllers;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.delegate = self;
self.dataSource = self;
[self didMoveToParentViewController:self];
UIStoryboard *tutorialStoryboard = [UIStoryboard storyboardWithName:@"TutorialStoryboard" bundle:[NSBundle mainBundle]];
UIViewController *tuto1 = [tutorialStoryboard instantiateViewControllerWithIdentifier:@"TutorialPageViewController_1"];
UIViewController *tuto2 = [tutorialStoryboard instantiateViewControllerWithIdentifier:@"TutorialPageViewController_2"];
myViewControllers = @[tuto1, tuto2, tuto1, tuto2];
self.index = 0;
[self setViewControllers:@[tuto1] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}
- (UIViewController *)viewControllerAtIndex:(NSUInteger)index {
return myViewControllers[index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger index = self.index;
if (index == 0) { return nil; }
// Decrease the index by 1 to return
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = self.index;
index++;
if (index > [myViewControllers count]) { return nil; }
return [self viewControllerAtIndex:index];
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
// The number of items reflected in the page indicator.
return [myViewControllers count];
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
// The selected item reflected in the page indicator.
return 0;
}
@end
答案 0 :(得分:61)
现在很容易做到这一点只使用故事板。
这种“刷屏全屏教程”作为应用程序“介绍”很受欢迎,因此我将该课程称为IntroPages
以下的课程。
步骤1,创建一个UIPageViewController的容器视图。
如果是iOS新用户,则此处为container view tutorial。
(注意:如果您不知道如何将容器视图更改为UIPageViewController,请向下滚动到该教程的“如何更改...”部分。
您可以将容器设置为您想要的任何形状。与任何容器视图一样,它可以是全屏或屏幕的一小部分 - 无论你想要什么。
第2步,
制作四个简单的视图控制器,可以你想要的任何东西 - 图像,文本,表格,任何东西。 (示例中为紫色。)
请注意,他们只是坐在您的故事板上,不要将它们链接到任何内容。
第3步,您必须设置这四个页面的ID 。 “id1”,“id2”,“id4”,“id4”很好。
第4步,复制并粘贴!这是IntroPages类,
class IntroPages: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
let p1: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "id1")
let p2: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "id2")
let p3: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "id3")
// etc ...
pages.append(p1)
pages.append(p2)
pages.append(p3)
// etc ...
setViewControllers([p1], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController)-> UIViewController? {
let cur = pages.index(of: viewController)!
// if you prefer to NOT scroll circularly, simply add here:
// if cur == 0 { return nil }
let prev = abs((cur - 1) % pages.count)
return pages[prev]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController)-> UIViewController? {
let cur = pages.index(of: viewController)!
// if you prefer to NOT scroll circularly, simply add here:
// if cur == (pages.count - 1) { return nil }
let nxt = abs((cur + 1) % pages.count)
return pages[nxt]
}
func presentationIndex(for pageViewController: UIPageViewController)-> Int {
return pages.count
}
}
(查看注释 - 根据您的喜好,可以使用循环或线性分页的代码。)
这就是它的全部 - 你已经完成了。
您只需在故事板上设置过渡样式,
你很可能想要“滚动”,而不是另一个。
答案 1 :(得分:19)
对于想要查看工作页面滚动(向前/向后)的人
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger currentIndex = [myViewControllers indexOfObject:viewController];
// get the index of the current view controller on display
if (currentIndex > 0)
{
return [myViewControllers objectAtIndex:currentIndex-1];
// return the previous viewcontroller
} else
{
return nil;
// do nothing
}
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger currentIndex = [myViewControllers indexOfObject:viewController];
// get the index of the current view controller on display
// check if we are at the end and decide if we need to present
// the next viewcontroller
if (currentIndex < [myViewControllers count]-1)
{
return [myViewControllers objectAtIndex:currentIndex+1];
// return the next view controller
} else
{
return nil;
// do nothing
}
}
只是为了添加EditOR的这个好答案,如果您更喜欢“round and around”分页,请执行以下操作:仍然使用相同的EditOR技术
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger currentIndex = [myViewControllers indexOfObject:viewController];
--currentIndex;
currentIndex = currentIndex % (myViewControllers.count);
return [myViewControllers objectAtIndex:currentIndex];
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger currentIndex = [myViewControllers indexOfObject:viewController];
++currentIndex;
currentIndex = currentIndex % (myViewControllers.count);
return [myViewControllers objectAtIndex:currentIndex];
}
答案 2 :(得分:11)
使用private static final Service [] employeeList = new Employee [10];
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args){
// First name / Last name / Employee Number
final Employee FakeEmployee0 = new Employee("Steve", "Holt", "2345");
final Employee FakeEmployee1 = new Employee("Steve", "Molt", "2111");
final Employee FakeEmployee2 = new Employee("Steve", "Sholt", "245");
final Employee FakeEmployee3 = new Employee("Steve", "Colt", "2222");
final Employee FakeEmployee4 = new Employee("Steve", "Wolt", "25");
final Employee FakeEmployee5 = new Employee("Boy", "Blue", "1");
final Employee FakeEmployee6 = new Employee("Boy", "Wonder", "8999");
final Employee FakeEmployee7 = new Employee("Boy", "George", "500");
final Employee FakeEmployee8 = new Employee("Will", "Smith", "123");
final Employee FakeEmployee9 = new Employee("Will", "Ferret", "23");
employeeList [0] = FakeEmployee0;
employeeList [1] = FakeEmployee1;
employeeList [2] = FakeEmployee2;
employeeList [3] = FakeEmployee3;
employeeList [4] = FakeEmployee4;
employeeList [5] = FakeEmployee5;
employeeList [6] = FakeEmployee6;
employeeList [7] = FakeEmployee7;
employeeList [8] = FakeEmployee8;
employeeList [9] = FakeEmployee9;
// Search for employees by first name:
private static void searchNames(){
System.out.println("Enter employee's first name: ");
String nameCheck = sc.nextLine();
for (int i = 0; i < employeeList.length; i++){
if (employeeList[i].getFirstName().startsWith(nameCheck)){
System.out.println("ID No: " + employeeList[i].getIdNum() + " - "
+ employeeList[i].getLastName() + " " +
employeeList[i].getFirstName());
}
else {
System.out.println("No Matching employee records found!");
}
}
}
类的Swift代码扩展Joe Blow's answer:
UIPageViewController
在故事板设置的using UIPageViewController with container view上阅读更多内容。
答案 3 :(得分:5)
在Storyboard中似乎有很多关于UIPageViewController的问题。
以下是some demo code,向您展示如何在故事板中将UIPageViewController用作独立的全屏视图或UIContainerView,如果您只想在屏幕的一小部分区域进行分页。
答案 4 :(得分:1)
针对Swift 3进行了更新:
class YourPageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var pages = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
let page1: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "page1")
let page2: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "page2")
pages.append(page1)
pages.append(page2)
setViewControllers([page1], direction: UIPageViewControllerNavigationDirection.forward, animated: false, completion: nil)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
let previousIndex = abs((currentIndex - 1) % pages.count)
return pages[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
let nextIndex = abs((currentIndex + 1) % pages.count)
return pages[nextIndex]
}
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
return pages.count
}
}
答案 5 :(得分:0)
要使用@samwize的答案进行无限回滚,您需要添加条件以检查负值。否则,您只需在第一页和第二页之间切换。只有在计划有两页以上时才需要这样做。
func pageViewController(_ pageViewController: UIPageViewController,
viewControllerBefore viewController: UIViewController) -> UIViewController? {
let currentIndex = pages.index(of: viewController)!
var previousIndex = (currentIndex - 1) % pages.count
if previousIndex < 0 {previousIndex = pages.count - 1}
return pages[previousIndex]
}
答案 6 :(得分:0)
Swift 5 的答案:
import UIKit
class MyPageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var allViewControllers = [UIViewController]()
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
let vc1: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "viewController1")
let vc2: UIViewController! = storyboard?.instantiateViewController(withIdentifier: "viewController2")
allViewControllers = [vc1, vc2]
self.setViewControllers([vc1], direction: UIPageViewController.NavigationDirection.forward, animated: false)
}
// UIPageViewControllerDataSource
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?
{
let currentIndex = allViewControllers.firstIndex(of: viewController)!
return currentIndex == 0 ? nil : allViewControllers[currentIndex-1]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?
{
let currentIndex = allViewControllers.firstIndex(of: viewController)!
return currentIndex == allViewControllers.count-1 ? nil : allViewControllers[currentIndex+1]
}
func presentationCount(for pageViewController: UIPageViewController) -> Int
{
return allViewControllers.count
}
func presentationIndex(for pageViewController: UIPageViewController) -> Int
{
return 0
}
}
答案 7 :(得分:-1)
问题在于您不正确地重用UIViewController
个实例:
myViewControllers = @[tuto1, tuto2, tuto1, tuto2];
我建议您使用NSMutableSet
作为可重复使用的UIViewController
个实例池。
在viewControllerBeforeViewController:
和viewControllerBeforeViewController:
中使用NSMutableSet
搜索您的NSPredicate
,找到UIViewController
,parentViewController
等于nil
。如果找到一个,请将其退回。如果没有,请实例化一个新的,将其添加到NSMutableSet
然后将其返回。
当你完成并且你的测试正在通过时,你可以将池提取到它自己的类中。