gpt4 book ai didi

ios - 点击 UIButton 后如何在 UIPageViewController 中添加新的 View Controller ?

转载 作者:可可西里 更新时间:2023-11-01 05:04:44 27 4
gpt4 key购买 nike

我想知道如何实现会影响 UIPageViewController 模型的按钮。例如,我希望我的 UIPageViewController 模型数组加载其中的单个对象,当点击一个按钮时,将添加一个新的 View Controller ,并将自动翻转页面或类似的东西(如在 Notes 应用程序中)。删除用户正在查看的当前对象也是如此。

到目前为止,我尝试对我的 Root View Controller 实现一些 IBAction,但到目前为止没有成功。

下面是我如何实现我的 ViewController 类:

@implementation ViewController

@synthesize modelArray = _modelArray;
@synthesize pageVC = _pageVC;

#pragma mark - UIPageViewControllerDataSource Methods

// Returns the view controller before the given view controller. (required)
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentVC *)viewController labelContents]];
if(currentIndex==0)
return nil;

ContentVC *cVC = [[ContentVC alloc] init];
cVC.labelContents = [self.modelArray objectAtIndex:currentIndex-1];
return cVC;
}

// Returns the view controller after the given view controller. (required)
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentVC *)viewController labelContents]];
if(currentIndex==self.modelArray.count-1)
return nil;

ContentVC *cVC = [[ContentVC alloc] init];
cVC.labelContents = [self.modelArray objectAtIndex:currentIndex+1];
return cVC;
}

#pragma mark - UIPageViewControllerDelegate Methods
// Returns the spine location for the given orientation.
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
if(UIInterfaceOrientationIsPortrait(orientation)){
// Set the array with only 1 view controller
UIViewController *currentVC = [self.pageVC.viewControllers objectAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:currentVC];
[self.pageVC setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];

// Set the doubleSided property to NO
self.pageVC.doubleSided = NO;
// Return the spine location
return UIPageViewControllerSpineLocationMin;
} else { // if landscape
NSArray *viewControllers = nil;
ContentVC *currentVC = [self.pageVC.viewControllers objectAtIndex:0];
NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentVC *)viewControllers labelContents]];
if(currentIndex==0 || currentIndex %2 == 0){
UIViewController *nextViewController = [self pageViewController:self.pageVC viewControllerAfterViewController:currentVC];
viewControllers = [NSArray arrayWithObjects:currentVC, nextViewController, nil];
} else {
UIViewController *previousVC = [self pageViewController:self.pageVC viewControllerBeforeViewController:currentVC];
viewControllers = [NSArray arrayWithObjects:previousVC, currentVC, nil];
}
// Set the view controllers as property of the UIPageViewController
[self.pageVC setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
return UIPageViewControllerSpineLocationMid;
}

}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
[super viewDidLoad];

// Instantiate the model array
self.modelArray = [[NSMutableArray alloc] init];
[self.modelArray addObject:@"Page One"];
NSLog(@"%@", self.modelArray);

// Instantiate the UIPageViewController
self.pageVC = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

// Assign the delegate and datasource as self
self.pageVC.delegate = self;
self.pageVC.dataSource = self;

// Set the initial view controllers
ContentVC *cVC = [[ContentVC alloc] initWithNibName:@"ContentVC" bundle:nil];
cVC.labelContents = [self.modelArray objectAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:cVC];
[self.pageVC setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

// Add the pageViewController as the childViewController
[self addChildViewController:self.pageVC];

// Add the view of pageViewController to the currentView
[self.view addSubview:self.pageVC.view];

// Call didMoveToParentViewController: of the childViewController, the UIPageViewController instance in our case.
[self.pageVC didMoveToParentViewController:self];

// Assign the gestureRecognizers property of the pageViewController to the view's gestureRecognizers property
self.view.gestureRecognizers = self.pageVC.gestureRecognizers;

}

非常感谢!

最佳答案

UIPageViewController 使用数据源获取下一个或上一个 View Controller 。所以解决方案是在触摸按钮后将新的 View Controller 添加到数据源。

假设您的数据源是作为 NSArray 实现的(请参阅 XCode 的基于页面的应用程序模板作为示例)您只需将新的 vc 添加到该数组并通过调用设置新的 vc [UIPageViewController setViewControllers:direction:animated:completion:].

由于您没有提供有关如何实现层次结构的任何详细信息,因此我无法提供更具体的信息。

编辑:

现在我有了一些代码,下面是我要做的:

首先,我不会保存 labelContents,而是将 View Controller 本身保存在 modelArray 中。除此之外,您当前的设计在每次更改页面时都会创建一个新的 ContentVC。这是很多不必要的开销。下面是我将如何实现它:

(顺便说一句,您应该想一个比 labelContents 更具描述性的名称。现在如果只有一个标签可能没问题,但如果您将来添加更多标签会怎么样?)

- (ContentVC *)contentViewControllerWithLabelContents:(NSString *)labelContents
{
ContentVC *vc = [[ContentVC alloc] initWithNibName:@"ContentVC" bundle:nil];
vc.labelContents = labelContents;
return vc;
}

- (void)viewDidLoad
{
NSMutableArray *vcs = [NSMutableArray array];
[vcs addObject:[self contentViewControllerWithLabelContents:@"Page One"]];
[vcs addObject:[self contentViewControllerWithLabelContents:@"Page Two"]];
//...
self.modelArray = vcs;
}


#pragma mark - UIPageViewControllerDataSource Methods

// Returns the view controller before the given view controller. (required)
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger currentIndex = [self.modelArray indexOfObject:viewController];
if(currentIndex == 0)
return nil;

ContentVC *cVC = [self.modelArray objectAtIndex:currentIndex - 1];
return cVC;
}

// Returns the view controller after the given view controller. (required)
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger currentIndex = [self.modelArray indexOfObject:viewController];
if(currentIndex == self.modelArray.count - 1)
return nil;

ContentVC *cVC = [self.modelArray objectAtIndex:currentIndex + 1];
return cVC;
}

评论中的代码:

- (IBAction)newButtonTapped:(id)sender 
{
if(sender){
[self.modelArray addObject:@"Page Two"];
ContentVC *newVC = [[ContentVC alloc] initWithNibName:@"ContentVC" bundle:nil];
NSArray *arr = [NSArray arrayWithObject:newVC];
[self.pageVC setViewControllers:arr direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
NSLog(@"%@", self.modelArray);
}
}

不起作用,因为您没有设置 ContentVClabelContents。因此,您基本上最终会调用 [self.modelObject indexOfObject:nil][self.modelObject indexOfObject:@""] ,具体取决于您对 labelContents 。由于它们都不在数组中,因此调用返回 NSNotFound,在 64 位系统上它被转换为 NSIntegerMax,即 2147483647。稍后您尝试在索引 NSIntegerMax - 1 处访问您的 modelArray 并引发 NSRangeException

因此可以通过在 newButtonTapped: 方法中设置 labelContents 来解决这个问题,或者如果您按照我的建议重新设计代码:

- (IBAction)newButtonTapped:(id)sender 
{
if(sender){
ContentVC *newVC = [self contentViewControllerWithLabelContents:@"Page Two"];
[self.modelArray addObject:newVC];

NSArray *newVCs = nil;

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation) || self.modelArray.count == 1)
newVCs = @[newVC];
else
{
NSUInteger secondLastIndex = self.modelArray.count - 2;
id previousVC = [self.modelArray objectAtIndex:secondLastIndex];
newVCs = @[previousVC, newVC];
}

[self.pageVC setViewControllers:newVCs direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}
}

关于ios - 点击 UIButton 后如何在 UIPageViewController 中添加新的 View Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13222684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com