Duplicating Android ViewPager type functionality w

2019-05-26 08:10发布

问题:

I'm trying to duplicate the Android UI left-right gesture type of navigation. This is used in the Android Marketplace, but also on the iPhone version of Google+.

Here is a youtube link of the Google+ in action that I am trying to mimic. http://www.youtube.com/watch?v=RYW9yxhhhPU&t=0m25s

As you can see in the video above, there is a small scrolling area on top of the main viewing area. The small scrolling area holds the text "Incoming", "Circles", "Nearby" and shifts between them when the main page is scrolled.

What I've tried to do (unsuccessfully) is making two UIScrollViews. One for the main area and one for the smaller area. I set the smaller UIScrollView to shift left or right at 0.5x the the contentOffset.x of the main scrollView.

The look is somewhat similar, but I'm having tremendous difficulty getting the text labels in the smaller scrollview to line up precisely in the left, middle, and right positions.

I'm not sure if this is the right way to go about doing this, but if there are any other ways, I'd love to hear them.

I'd really appreciate any help on this! Thank you!

回答1:

I have to do this for a project as well. I've got it mostly working. Minus the animation when scrolling it. I've started a project on github for this. I will be adding to it as I go, but in the mean time this should be a good jumping off point. The demo can be found here, https://github.com/btate/BTViewPager



回答2:

I think the best approach would be to create a paging UIScrollView. Then place both the navigation and main content UIScroll in one UIView/page. When you swipe, the pages will lock into place. It looks like the navigation is animated a bit, but I would assume that Google used this approach.

Here's a tutorial with sample code to give you exactly what you'd need for paging scroll view.

http://www.iosdevnotes.com/2011/03/uiscrollview-paging/

To accomplish the navigation labels, I'd subclass UIView and add the view right above the main scroll view. Then tell the view to reorganise the labels. Probably in `- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView

Here's something I quickly wrote to demonstrate what I mean. This would be in a subclass of UIView

- (void)addLablesForItems:(NSArray *)items
{

    for (NSString *s in items)
    {
        UILabel *l = [[UILabel alloc] initWithFrame:CGRectZero];
        l.text = s;
        [self addSubview:l];
    }

    [self layoutSubviews];
}

- (void)layoutSubviews
{

    for (UIView *l in [self subviews])
    {
        if ([l isKindOfClass:[UILabel class]])
        {
            int index = [[self subviews] indexOfObject:l];
            if (index == 0)
            {
                l.frame = CGRectMake(0, 0, 20, 20);
            }
            else
            {
                UILabel *previousL = (UILabel *)[[self subviews] objectAtIndex:index -1];

                l.frame = CGRectMake(previousL.frame.origin.x+previousL.frame.size.width, 0, 20, 20);
            }
        }
    }
}    

- (void)shiftLabels:(int)direction
{
    //0 is left
    //1 is right    
    for (UIView *l in [self subviews])
    {
        if ([l isKindOfClass:[UILabel class]])
        {
            if (direction == 0)
            {
                int newOrigin = l.frame.origin.x - l.frame.size.width;
                if (newOrigin < 0)
                {
                    newOrigin = self.frame.size.width - l.frame.size.width;
                }
                [UIView animateWithDuration:.5 animations:^{

                    l.frame = CGRectMake(newOrigin, 0, 20, 20);
                }];
            }
            if (direction == 1)
            {
                int newOrigin = l.frame.origin.x + l.frame.size.width;
                if (newOrigin < 0)
                {
                    newOrigin = self.frame.origin.x;
                }

                [UIView animateWithDuration:.5 animations:^{
                    l.frame = CGRectMake(newOrigin, 0, 20, 20);                    
                }];
            }
        }
    }
}

`