gpt4 book ai didi

ios - UIPageViewController 的 DataSource 代表一次滑动连续调用 2 次

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:27:56 27 4
gpt4 key购买 nike

这可能看起来像以前问过的问题(PageViewController delegate functions called twice),但问题是我无法将该解决方案应用于我的问题。

您可能会注意到,我正在开发一个日历应用程序并使用 UIPageViewController 来管理我的年度日历显示。如您所见,我正在使用 UIPageViewControllerTransitionStylePageCurl 并且当用户 curl 页面(向前/向后)时,他们各自的委托(delegate)被调用两次,这根据执行的委托(delegate)给我 2 年的增量或减量。现在我需要找出导致此问题的原因并阻止它被执行两次。

我知道在那些给我的下一页或上一页的委托(delegate)中返回一个 viewController 很重要,因此我只是刷新 viewController 的 View ,以便我可以用新数据呈现 View 。我还尝试了另一个名为 willTransitionToViewControllers 的委托(delegate),但不会让我到任何地方,因为 willTransitionToViewControllers 只会在之后执行viewControllerAfterViewController 和 viewControllerBeforeViewController。

有人帮助我理解并解决这个问题。

 - (void)addCalendarViews
{
CGRect frame = CGRectMake(0., 0., self.view.frame.size.width, self.view.frame.size.height);

pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:UIPageViewControllerSpineLocationNone] forKey:UIPageViewControllerOptionSpineLocationKey]];
pageViewController.doubleSided = YES;
pageViewController.delegate = self;
pageViewController.dataSource = self;

YearCalendarViewController *yearController = [[YearCalendarViewController alloc] init];


NSArray *viewControllers = [NSArray arrayWithObject:yearController];

[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionReverse
animated:YES
completion:nil];

[self addChildViewController:pageViewController];
[self.view addSubview:pageViewController.view];

[pageViewController didMoveToParentViewController:self];

CGRect pageViewRect = yearController.view.bounds;
self.pageViewController.view.frame = pageViewRect;


viewCalendarMonth = [[SGMonthCalendarView alloc] initWithFrame:frame];
[self.view addSubview:viewCalendarMonth];

arrayCalendars = @[pageViewController.view, viewCalendarMonth];
}




-(UIViewController*)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSDate *currentDate = [[SGSharedDate sharedManager] currentDate];
NSDateComponents *currentDateComp = [NSDate returnDateComponentsForDate:currentDate];
self.nextDate = [NSDate dateWithYear:currentDateComp.year+1 month:currentDateComp.month day:currentDateComp.day];
[[SGSharedDate sharedManager] setCurrentDate:nextDate];


{
//I m reloading viewController's view here to display the new set of data for the increamented date.
}
NSLog(@"After Dates====>%@", nextDate);
return viewController;
}



-(UIViewController*)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSDate *currentDate = [[SGSharedDate sharedManager] currentDate];
NSDateComponents *currentDateComp = [NSDate returnDateComponentsForDate:currentDate];
nextDate = [NSDate dateWithYear:currentDateComp.year-1 month:currentDateComp.month day:currentDateComp.day];
[[SGSharedDate sharedManager] setCurrentDate:nextDate];


{
//I m reloading viewController's view here to display the new set of data for the decremented date.
}
NSLog(@"Before Dates====>%@", nextDate);
return viewController;
}

最佳答案

UIPageController 倾向于向前(和向后)缓存,因此当您从 View Controller N 向前滑动时,N+1 加载 BUT 所以N+2 静默执行,因此如果您滑动两次,您的内容已经加载。

但是由于您在委托(delegate)方法中有一个不可见的副作用(递增日期),您会受到这种影响。

我的建议是从您的委托(delegate)中删除约会副作用,并以某种方式将日期代码绑定(bind)到呈现的 View Controller (委托(delegate)或属性),然后捕获 pageController 的 didFinishAnimating 方法。

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {

if (completed) {

if ([[self.pageViewController.viewControllers firstObject] isKindOfClass:[MyCalenderViewController class]]) {

currentDate = [self workOutCurrentDateForVC:[self.pageViewController.viewControllers firstObject]];

}

}

}

副作用是一种代码味道。尽量避免。

编辑

我刚刚注意到您正在回收 View Controller 并使用新的日期点重新加载它。不要这样做。您需要将 View Controller 视为书中的一页。因此,生成一个新的并为这个月设置它......

简单举个例子...

@interface YearViewController : UIViewController 

@property NSDate *focusedYear;

-(instancetype)initWithYear:(NSDate)adate;

@end

@implementation YearViewController

-(instancetype)initWithYear:(NSDate)adate {
self = [super initWithNibName:nil bundle:nil];
if(self) {
self.focusedYear = adate;
....
}
}

@end

因此在页面 Controller 委托(delegate)中,您只需根据前一个页面的日期(以及您的分页方向)提供一个新的“页面”

-(UIViewController*)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
YearViewController *yvc = (YearViewController *)viewController;

NSDate *currentDate = yvc.focusedYear;
NSDateComponents *currentDateComp = [NSDate returnDateComponentsForDate:currentDate];
NSDate *nextDate = [NSDate dateWithYear:currentDateComp.year+1 month:currentDateComp.month day:currentDateComp.day];

YearViewController *freshYVC = [[YearViewController alloc] initWithDate:nextDate];

return freshYVC;
}

关于副作用的评论仍然有效。

关于ios - UIPageViewController 的 DataSource 代表一次滑动连续调用 2 次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24998102/

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