Kyl*_*yle 62 iphone objective-c ios uipageviewcontroller
我发现了一些关于如何UIPageViewController
跳转到特定页面的问题,但我注意到跳跃的一个额外问题,没有任何答案似乎承认.
没有进入我的iOS应用程序的细节(类似于分页日历),这是我正在经历的.我声明了一个UIPageViewController
,设置当前的视图控制器,并实现一个数据源.
// end of the init method
pageViewController = [[UIPageViewController alloc]
initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
options:nil];
pageViewController.dataSource = self;
[self jumpToDay:0];
}
//...
- (void)jumpToDay:(NSInteger)day {
UIViewController *controller = [self dequeuePreviousDayViewControllerWithDaysBack:day];
[pageViewController setViewControllers:@[controller]
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:nil];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSInteger days = ((THDayViewController *)viewController).daysAgo;
return [self dequeuePreviousDayViewControllerWithDaysBack:days + 1];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSInteger days = ((THDayViewController *)viewController).daysAgo;
return [self dequeuePreviousDayViewControllerWithDaysBack:days - 1];
}
- (UIViewController *)dequeuePreviousDayViewControllerWithDaysBack:(NSInteger)days {
return [[THPreviousDayViewController alloc] initWithDaysAgo:days];
}
Run Code Online (Sandbox Code Playgroud)
编辑注意:我为出列方法添加了简化代码.即使有这个亵渎的实现,我也有与页面顺序完全相同的问题.
初始化全部按预期工作.增量分页也都可以正常工作.问题是,如果我jumpToDay
再次打电话,订单会混乱.
如果用户在第-5天并且跳到第1天,则向左滚动将再次显示第-5天而不是适当的第0天.这似乎与如何UIPageViewController
保持对附近页面的引用有关,但我可以找不到任何会强制它刷新缓存的方法的引用.
有任何想法吗?
dji*_*i33 84
编程iOS6,由Matt Neuburg记录这个确切的问题,我实际上发现他的解决方案比目前接受的答案感觉好一些.该解决方案效果很好,具有负面的副作用,即在之前/之后动画到图像,然后用所需页面进行剧烈的替换.我觉得这是一种奇怪的用户体验,Matt的解决方案可以解决这个问题.
__weak UIPageViewController* pvcw = pvc;
[pvc setViewControllers:@[page]
direction:UIPageViewControllerNavigationDirectionForward
animated:YES completion:^(BOOL finished) {
UIPageViewController* pvcs = pvcw;
if (!pvcs) return;
dispatch_async(dispatch_get_main_queue(), ^{
[pvcs setViewControllers:@[page]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO completion:nil];
});
}];
Run Code Online (Sandbox Code Playgroud)
小智 37
所以我遇到了和你一样的问题,我需要能够"跳转"到一个页面,然后当我打开一个页面时发现'命令乱了'.据我所知,页面视图控制器肯定会缓存视图控制器,当你"跳转"到页面时,你必须指定方向:前进或后退.然后假设新视图控制器是前一个视图控制器的"邻居",因此当您回击时自动呈现先前的视图控制器.我发现这只发生在你使用的时候UIPageViewControllerTransitionStyleScroll
而不是UIPageViewControllerTransitionStylePageCurl
.页面卷曲样式显然不会执行相同的缓存,因为如果您"跳转"到某个页面然后向后回拨它会将pageViewController:viewController(Before/After)ViewController:
消息传递到数据源,从而使您能够提供正确的邻居视图控制器.
解决方案:当执行"跳转"到页面时,您可以首先跳转到跳转到页面的邻居页面(animated:NO
),然后在该跳转的完成块中跳转到所需页面.这将更新缓存,以便在您回拨时,将显示正确的邻居页面.缺点是你需要创建两个视图控制器; 你跳到的那个和手势后应该显示的那个.
以下是我为其编写的类别的代码UIPageViewController
:
@implementation UIPageViewController (Additions)
- (void)setViewControllers:(NSArray *)viewControllers direction:(UIPageViewControllerNavigationDirection)direction invalidateCache:(BOOL)invalidateCache animated:(BOOL)animated completion:(void (^)(BOOL finished))completion {
NSArray *vcs = viewControllers;
__weak UIPageViewController *mySelf = self;
if (invalidateCache && self.transitionStyle == UIPageViewControllerTransitionStyleScroll) {
UIViewController *neighborViewController = (direction == UIPageViewControllerNavigationDirectionForward
? [self.dataSource pageViewController:self viewControllerBeforeViewController:viewControllers[0]]
: [self.dataSource pageViewController:self viewControllerAfterViewController:viewControllers[0]]);
[self setViewControllers:@[neighborViewController] direction:direction animated:NO completion:^(BOOL finished) {
[mySelf setViewControllers:vcs direction:direction animated:animated completion:completion];
}];
}
else {
[mySelf setViewControllers:vcs direction:direction animated:animated completion:completion];
}
}
@end
Run Code Online (Sandbox Code Playgroud)
你可以做些什么来测试这个是创建一个新的'基于页面的应用程序'并添加一个'转到'按钮,它将"跳转"到某个日历月,然后回击.务必设置要过渡的过渡样式.
我使用这个功能(我总是在风景,2页模式)
-(void) flipToPage:(NSString * )index {
int x = [index intValue];
LeafletPageContentViewController *theCurrentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
NSUInteger retreivedIndex = [self indexOfViewController:theCurrentViewController];
LeafletPageContentViewController *firstViewController = [self viewControllerAtIndex:x];
LeafletPageContentViewController *secondViewController = [self viewControllerAtIndex:x+1 ];
NSArray *viewControllers = nil;
viewControllers = [NSArray arrayWithObjects:firstViewController, secondViewController, nil];
if (retreivedIndex < x){
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
} else {
if (retreivedIndex > x ){
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:NULL];
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的Swift解决方案,用于以下子类UIPageViewController
:
假设您存储一个viewControllers数组viewControllerArray
和当前页面索引updateCurrentPageIndex
.
private func slideToPage(index: Int, completion: (() -> Void)?) {
let tempIndex = currentPageIndex
if currentPageIndex < index {
for var i = tempIndex+1; i <= index; i++ {
self.setViewControllers([viewControllerArray[i]], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: {[weak self] (complete: Bool) -> Void in
if (complete) {
self?.updateCurrentPageIndex(i-1)
completion?()
}
})
}
}
else if currentPageIndex > index {
for var i = tempIndex - 1; i >= index; i-- {
self.setViewControllers([viewControllerArray[i]], direction: UIPageViewControllerNavigationDirection.Reverse, animated: true, completion: {[weak self] (complete: Bool) -> Void in
if complete {
self?.updateCurrentPageIndex(i+1)
completion?()
}
})
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
47324 次 |
最近记录: |