- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
这可能看起来像以前问过的问题(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/
我正在尝试在我的 UITableView 上调用 reloadData。我在没有界面生成器的情况下制作我的应用程序。 此代码适用于 Interface Builder,但似乎没有。 当我将我的代码与我
有人可以解释 UIAlertView 的委托(delegate)是如何工作的吗?它是自动调用还是我必须调用它?例如: - (void)alertView:(UIAlertView *)alertVie
编辑:好吧,根据其他人的建议,我创建了一个最小的示例......并且它有效,因此我将在未来与任何人分享它。这是工作代码: #include #include using namespace std
unicode 是 ,它被用在 XML 文档中。 最佳答案 查看图表:unicodelookup.com 换行符。 关于html - unicode字符是什么 代表?,我们在Stack Overflo
我有一个应用程序,可以以编程方式在配置的 Facebook 页面上发帖。我的应用程序显然已批准管理页面和发布页面权限,并且我正在使用页面访问 token 从现在开始一切正常,但最近当我在页面提要上发布
代表 NCAA 男子篮球分组的最佳数据库模式是什么?如果您不熟悉,请点击以下链接:http://www.cbssports.com/collegebasketball/mayhem/brackets/
所以我一直在阅读这个关于如何使用 Frida 的教程:https://www.frida.re/docs/functions/我遇到过以下情况: $ ./client 127.0.0.1 connec
委托(delegate)函数返回之前是否需要调用replyHandler?我需要进行几次 Web 服务 API 调用才能回复,以下实现正确吗? func session(_ session: WCSe
下面提到的是我的 textField 委托(delegate)方法,我正在使用 IQKeyBoardSwift 作为智能键盘。我尝试移除我的键盘,但我仍然没有收到任何关于接受“开始触摸”的方法的调用
我有一个表格 View ,其中几乎没有用于数据输入的文本字段和弹出窗口。我想将其中一些表示为强制性的。我不知道如何讨厌星号。任何帮助将不胜感激。 最佳答案 我认为你可以使用自定义 UITableVie
例如,我知道如何使用 numpy 对数组进行切片 v[1, :, :] 现在我想要一个函数将切片 (1,1,None) 作为输入并返回 v[1,:,:] 问题是我不知道如何表示省略号 最佳答案 您可以
修订... 应用程序的关键是与数据库服务器通信。服务器对应用程序的响应都是 XML 格式的。有几个屏幕。例如,屏幕 1 列出了用户的信息,屏幕 2 列出了用户过去的交易,允许新交易,等等。 这是我的
我想知道映射/表示内存的最佳方式是什么。我的意思是,例如,如何描述一个结构及其所有字段都被序列化。 我正在创建一个 RPC 库,它将使用 dwarf 调试数据创建客户端和服务器,因此我需要创建一个函数
如果我有一个实现了两个协议(protocol)的 View Controller : @interface CustomerOperationsViewController : UIViewContr
在 Objective-C 中我可以做这样的事情: @property (nonatomic, weak) id someObject; 如何在swift中做到这一点?我试过这个: let someO
我成功地使用了相当棒的 connection:didReceiveAuthenticationChallenge: NSURLConnectionDelegate 委托(delegate)方法。很酷。
我正在寻找原始数据类型的 @NonNull 等效 Java 注释。我知道原始数据不能为 null,但我找不到替代方法。 我想要实现的在逻辑上等同于: int mPageNumber; public v
我正在学习 Git,如果我能描述代表 Git 存储库的数学结构,那就太好了。例如:它是一个有向无环图;它的节点代表提交;它的节点有代表分支等的标签(每个节点最多一个标签,没有标签使用两次)。(我知道这
我看过很多与委托(delegate)相关的帖子,我想知道引用它们的正确方法。假设我有一个声明如下的对象: @interface MyViewController : UITableViewContro
我有这个类: public class Order { int OrderId {get; set;} string CustomerName {get; set;} } 我也声明下面的变
我是一名优秀的程序员,十分优秀!