1

我正在创建一个应用程序,它可以在书的页面之间左右滑动(像卡片组一样覆盖或显示),上下滑动将向下滑动(并覆盖)设置页面,或向上滑动(和揭示)到这本书的详细信息。

本质上,它是一个“卡片组”滑动功能,类似于我正在考虑使用的这个项目https://github.com/sweetmandm/CardSliderView-for-iOS,但是我需要垂直和水平“卡片组”滑动功能.

再举一个我正在查看的幻灯片/左封面/显示效果的示例,请查看新的 CNN 应用程序,您可以在其中在文章之间滑动。

我也考虑过使用 UIPageViewController,但是这不支持我正在寻找的“滑动和显示/滑动和覆盖”过渡,而只支持“向左或向右滑动”过渡,所以我不得不以某种方式破解它并使用多个 UIPageViewControllers,一个在上面,以允许“显示和覆盖”效果工作,仅使用 UIPageViewController 中的手势来允许用户滑动。

我熟悉 UIScrollview 上的 directionalLockEnabled 属性,但是我仍然想知道获得我正在寻找的效果的整体最佳方法是什么,一种同时支持垂直和水平的 UIScrollView?UIPageViewController?嵌套的 UIScrollviews?而不是玩弄 directionalLockEnabled 属性?还有什么?

实现我希望提供的确切用户体验的最佳方式是什么?

4

3 回答 3

1

好的,我使用嵌套的 UIScrollViews 找到了我自己问题的解决方案。我还向 github 添加了一个非常粗略的解决方案作为项目:https ://github.com/cohen72/InfiniteDeckScroller 。

对于水平滚动,我有三个水平滚动视图,一个嵌套在另一个中。UIScrollview 会自动处理每个的正确滚动。根据内容偏移量和正在滚动的滚动视图,我知道如何“重新排列/重新排序”嵌套的滚动视图。

这是我提出的解决方案的片段。

这个特殊的解决方案允许向上滑动以显示,但是我还没有实现向下滑动以覆盖,但是这样做会使用与水平解决方案相同的方法。

#define BOTTOM 1
#define MIDDLE 2
#define TOP 3
#define VERTICAL_SUB 4

- (void)viewDidLoad{

    [super viewDidLoad];

    UIScrollView *scroll1 = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    UIScrollView *scroll2 = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    UIScrollView *scroll3 = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    UIScrollView *scroll4 = [[UIScrollView alloc] initWithFrame:self.view.bounds];

    scroll1.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height * 1);
    scroll1.tag = BOTTOM;
    scroll1.pagingEnabled = YES;
    scroll1.bounces = NO;
    scroll1.delegate = self;
    [scroll1 addSubview:[self labelForScrollView:scroll1 withBgColor:[UIColor redColor]]];
    [scroll1 setContentOffset:CGPointMake(0, 0)];

    scroll2.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height * 1);
    scroll2.tag = MIDDLE;
    scroll2.pagingEnabled = YES;
    scroll2.bounces = NO;
    scroll2.delegate = self;
    [scroll2 addSubview:[self labelForScrollView:scroll2 withBgColor:[UIColor orangeColor]]];
    [scroll2 setContentOffset:CGPointMake(0, 0)];

    scroll3.contentSize = CGSizeMake(self.view.frame.size.width * 2, self.view.frame.size.height * 1);
    scroll3.tag = TOP;
    scroll3.pagingEnabled = YES;
    scroll3.bounces = NO;
    scroll3.delegate = self;
    [scroll3 addSubview:[self labelForScrollView:scroll3 withBgColor:[UIColor yellowColor]]];
    [scroll3 setContentOffset:CGPointMake(320, 0)];

    scroll4.contentSize = CGSizeMake(self.view.frame.size.width * 1, self.view.frame.size.height * 2);
    scroll4.delegate = self;
    scroll4.bounces = NO;
    scroll4.pagingEnabled = YES;
    scroll4.alwaysBounceVertical = NO;
    scroll4.tag = VERTICAL_SUB;

    [scroll4 addSubview:scroll1];
    [scroll1 addSubview:scroll2];
    [scroll2 addSubview:scroll3];
    [self.view addSubview:scroll4];

}

- (UILabel*)labelForScrollView:(UIScrollView*)scrollView withBgColor:(UIColor*)color{
    UILabel *lbl = [[UILabel alloc] initWithFrame:scrollView.bounds];
    lbl.textAlignment = NSTextAlignmentCenter;
    lbl.backgroundColor = color;
    lbl.text = [NSString stringWithFormat:@"ScrollView: %d", scrollView.tag];
    return lbl;
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    NSLog(@"content offset: %f, tag: %d ", scrollView.contentOffset.x, scrollView.tag);

    UIScrollView *newMiddleScrollView, *newBottomScrollView, *newTopScrollView;

    // swipe left

    if (scrollView.contentOffset.x == 0 && scrollView.tag == TOP) {
        newMiddleScrollView = (UIScrollView*)[self.view viewWithTag:TOP];
        newTopScrollView = (UIScrollView*)[self.view viewWithTag:BOTTOM];
        newBottomScrollView = (UIScrollView*)[self.view viewWithTag:MIDDLE];
    }

    // swipe right

    else if (scrollView.contentOffset.x == 320 && scrollView.tag == MIDDLE) {
        newMiddleScrollView = (UIScrollView*)[self.view viewWithTag:BOTTOM];
        newTopScrollView = (UIScrollView*)[self.view viewWithTag:MIDDLE];
        newBottomScrollView = (UIScrollView*)[self.view viewWithTag:TOP];
    }
    else {
        return;
    }

    newMiddleScrollView.tag = MIDDLE;
    newBottomScrollView.tag = BOTTOM;
    newTopScrollView.tag = TOP;

    newBottomScrollView.contentOffset = CGPointMake(0, 0);
    newMiddleScrollView.contentOffset = CGPointMake(0, 0);
    newTopScrollView.contentOffset = CGPointMake(320, 0);

    UIScrollView *verticalScrollView_sub = (UIScrollView*)[self.view viewWithTag:VERTICAL_SUB];

    [verticalScrollView_sub addSubview:newBottomScrollView];
    [newBottomScrollView addSubview:newMiddleScrollView];
    [newMiddleScrollView addSubview:newTopScrollView];

}
于 2012-12-24T14:42:55.437 回答
0

有很多不同的方法可以实现这一点,具体取决于您希望不同的控制器如何相互关联。幻灯片转换本身非常简单。我已经在一个控制器中以这种方式实现了它,该控制器是调用该方法的控制器的超类:

-(void)SlideInController:(RDSlideController *) next {
    next.presentingVC = self;
    next.view.frame = CGRectMake(self.view.frame.origin.x + 320, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
    [self.view.window addSubview:next.view];
    [UIView animateWithDuration:1 animations:^{
        next.view.frame = self.view.frame;
    } completion:^(BOOL finished) {
        self.view.window.rootViewController = next;
    }];
}

然后从新出现的控制器中,您可以调用此方法返回:

-(void)SlideOut {
    UIViewController *prev = self.presentingVC;
    prev.view.frame = self.view.frame;
    [self.view.window insertSubview:prev.view belowSubview:self.view];
    [UIView animateWithDuration:1 animations:^{
        self.view.frame = CGRectMake(self.view.frame.origin.x + 320, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
    } completion:^(BOOL finished) {
        self.view.window.rootViewController = prev;
    }];
}
于 2012-12-24T04:16:17.377 回答
0

这是一个很好的问题 - 如果我在这里错了,请纠正我,但听起来从左到右有任意数量的页面/卡片,但只有几张标准卡片从顶部或底部进入(您的设置和详细信息面板)。

如果是这种情况,那么您可能很想坚持使用UIPageController一些手势识别器旁边的东西。你设置你的页面控制器(或者你最终使用的任何控制器来实现你想要的卡片动画),然后添加两个手势识别器来向上滑动和向下滑动。

然后,您可以在收到这些手势时为您的详细信息/设置视图设置动画,从而为您提供类似卡片的界面,而无需打扰多个UIPageViewControllers视图或滚动视图。

如果您想要水平和垂直的任意数量的卡片,这种方法不是很好,但听起来好像不是这样。

于 2012-12-23T17:39:01.290 回答