我有UIPageViewController
,有3页。如何在按钮点击时切换到UIPageViewController
内的页面? (每个页面都是我在故事板中创建的单独UIViewController
。)
我尝试了很多代码,但是我在故事板中创建了UIPageViewController
时出现了错误,我将其设置为:
PageViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = self;
self.navigationController.navigationBarHidden = NO;
[self setViewControllers:@[[self.storyboard instantiateViewControllerWithIdentifier:@"Main"]]
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:nil];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[NavView2ViewController class]])
return nil;
return [self.storyboard instantiateViewControllerWithIdentifier:@"two"];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[NavViewController class]])
return nil;
return [self.storyboard instantiateViewControllerWithIdentifier:@"one"];
}
答案 0 :(得分:3)
您可以通过几种不同的方式执行此操作,具体取决于您希望如何构建应用程序的其余部分。
使用通知将允许您将子视图控制器与父页面视图控制器分离。它将足够灵活,允许整个应用程序中的其他代码控制哪个页面可见。然而,一个缺点是存在一定程度的间接性,并且不会立即显示触发页面更改的内容。
在PageViewController
上设置观察者,例如:
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = self;
self.navigationController.navigationBarHidden = NO;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleButtonTap:)
name:MyPageViewControllerButtonNotification
object:nil];
[self setViewControllers:@[[self.storyboard instantiateViewControllerWithIdentifier:@"Main"]]
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:nil];
}
- (void)handleButtonTap:(NSNotification *)notification
{
// Determine which page to move to based
// on the notification object or userInfo
}
并发布任何子视图控制器的通知:
- (void)buttonTapped:(id)sender
{
// Customise the sender or userInfo in order to
// pass further information with the notification.
[[NSNotificationCenter defaultCenter] postNotificationName:MyPageViewControllerButtonNotification
object:sender
userInfo:nil];
}
您需要在MyPageViewControllerButtonNotification
和您希望发布此通知的所有视图控制器共有的文件中创建字符串PageViewController
。
使用委托模式将在视图控制器和页面视图控制器之间提供比通知更紧密的耦合,这可能使以后扩展更加困难。这样做的好处是可以轻松跟踪页面更改的来源。
在页面视图控制器和子视图控制器共有的文件中定义协议:
@protocol PageControlDelegate <NSObject>
- (void)moveToPage:(NSUInteger)pageNumber;
@end
确保您的页面视图控制器符合该协议:
@interface PageViewController : UIPageViewController <PageControlDelegate>
(并在PageViewController.m
)
- (void)moveToPage:(NSUInteger)pageNumber
{
// switch to the appropriate page
}
当您为需要按钮交互的网页创建视图控制器时,您需要提供对PageViewController
的弱引用:
@interface SomeChildViewController : UIViewController
@property (nonatomic, weak) id<PageControlDelegate> pageControlDelegate;
@end
设置下一页时的示例分配:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[NavViewController class]])
return nil;
SomeChildViewController *childController = [self.storyboard instantiateViewControllerWithIdentifier:@"one"];
childController.pageControlDelegate = self;
return childController;
}
然后,您可以从具有pageControlDelegate
:
- (void)buttonTapped:(id)sender
{
NSUInteger pageNumber = // Decide which page to move to
[self.pageControlDelegate moveToPage:pageNumber];
}
答案 1 :(得分:0)
您可以根据需要随时拨打setViewController
。使用您想要的ViewController
再次调用它。您还可以通过访问ViewController
属性来尝试找到viewControllers
。但我认为,此属性只会显示正在显示的当前ViewController
。
答案 2 :(得分:0)
这就是我想出来的,它不需要黑魔法和代表。假设您拥有名为PageViewController
的自定义MyPageViewController
类,并在viewControllerList
中实例化并保留子视图控制器:
Swift 4
class MyPageViewController: UIPageViewController, UIPageViewControllerDataSource {
lazy var viewControllersList: [UIViewController] = {
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let first = storyBoard.instantiateViewController(withIdentifier: "FirstViewController")
let second = storyBoard.instantiateViewController(withIdentifier: "SecondViewController")
return [first,
second]
}()
}
现在在子视图控制器中,您可以通过以下方式切换到下一个视图控制器。在此示例中,我在选择表格行时执行切换:
Swift 4
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let pageViewController = self.parent as? MyPageViewController {
if let currentIndex = pageViewController.viewControllersList.index(of: self) {
guard (pageViewController.viewControllersList.count - currentIndex) > 1 else {
fatalError("Can't navigate to the next view controller!")
}
let nextViewController = pageViewController.viewControllersList[currentIndex + 1]
pageViewController.setViewControllers([nextViewController], direction: .forward, animated: true, completion: nil)
}
}
}