简体   繁体   中英

UIScrollView - selection like UIPickerView


I have two little problems with my UIScrollView.
I managed to create scroll view, which is similar to the picker view except that it's horizontal.

The problem n.1 is - How do I get the number which the user tapped?
The problem n.2 is - How do I make the scrollview to go round and round - never-ending?
A question - Is it possible to make some "selection indicator"?

Here is my code:

numberArray = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12", @"13", @"14", @"15", @"16", @"17", @"18", @"19", @"20", @"21", @"22", @"23", @"24", @"25", @"26", @"27", @"28", @"29", @"30", @"31", @"32", @"33", @"34", @"35", @"36", @"37", @"38", @"39", @"40", @"41", @"42", @"43", @"44", @"45", @"46", @"47", @"48", @"49", @"50", @"51", @"52", @"53", @"54", @"55", @"56", @"57", @"58", @"59", @"60", @"61", @"62", @"63", @"64", @"65", @"66", @"67", @"68", @"69", @"70", @"71", @"72", @"73", @"74", @"75", @"76", @"77", @"78", @"79", @"80", @"81", @"82", @"83", @"84", @"85", @"86", @"87", @"88", @"89", @"90", @"91", @"92", @"93", @"94", @"95", @"96", @"97", @"98", @"99", @"100", nil];

 masterDividerView = [[UIView alloc] initWithFrame:CGRectMake(0, 480, 320, 44)]; morePeople = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 53)]; morePeople.backgroundColor = [UIColor scrollViewTexturedBackgroundColor]; morePeople.delegate = self; [morePeople setBackgroundColor:[UIColor whiteColor]]; [morePeople setCanCancelContentTouches:NO]; morePeople.showsHorizontalScrollIndicator = NO; morePeople.showsVerticalScrollIndicator = NO; morePeople.clipsToBounds = NO; morePeople.scrollEnabled = YES; morePeople.pagingEnabled = NO; NSUInteger nimages = 0; NSInteger tot=0; CGFloat cx = 0; for (; ; nimages++) { NSString *label = [numberArray objectAtIndex:nimages]; if (tot==99) { break; } if (99==nimages) { nimages=0; } UILabel *labelView = [[UILabel alloc] init]; labelView.text = label; labelView.lineBreakMode = UILineBreakModeWordWrap; labelView.numberOfLines = 0; [labelView sizeToFit]; labelView.backgroundColor = [UIColor scrollViewTexturedBackgroundColor]; CGRect rect = labelView.frame; rect.size.height = 53; rect.size.width = 40; rect.origin.x = cx; rect.origin.y = 0; labelView.frame = rect; [morePeople addSubview:labelView]; cx += labelView.frame.size.width+5; tot++; } self.pageControl.numberOfPages = nimages; [morePeople setContentSize:CGSizeMake(cx, [morePeople bounds].size.height)]; [masterDividerView addSubview:morePeople]; [self.view addSubview:masterDividerView]; 

If anybody knows a good solution to this, I would be very happy!!!! :))

Your question is too wide to make a detailed answer, but yes, everything of what you're talking about can be solved in a quite easy way.

The problem n.1 is - How do I get the number which the user tapped?

If you mean to know what element is chosen by your UIScrollView at the moment, then it's not a problem: UIScrollView always knows its position (contentOffset), which gives you the easy possibility to define, which object is chosen (which object you're working with) now.

If you mean to know when the user tapped by his finger one of the elements of your "picker view" (UIScrollView), then I would say that the answer to this depends on how you actually represent your data (like if you see one or several elements of your scrollView at a time on your screen). But in any case you can easily solve this by using UITapGestureRecognizer. Smth like:

// add gesture recognizers to the scroll view 
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[singleTap setNumberOfTapsRequired:1];
[self.yourScrollView addGestureRecognizer:singleTap];
[singleTap release];

And then to scroll it programmatically in your selector you do smth like:

- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer
{
    CGPoint pointOfTouch = [gestureRecognizer locationInView:self.view];
    if ( (pointOfTouch.x > self.rightArrowMin) && (pointOfTouch.x < self.rightArrowMax) ) {
        [scrollView setContentOffset:CGPointMake(lastOffset + self.lengthOfLabel, 0) animated:YES];
    } else if ( (pointOfTouch.x > self.leftArrowMin) && (pointOfTouch.x < self.leftArrowMax) ) {
        [scrollView setContentOffset:CGPointMake(lastOffset - self.lengthOfLabel, 0) animated:YES];
    }
}

The problem n.2 is - How do I make the scrollview to go round and round - never-ending?

It can be solved if you know the algorithm of calculating the next/previous or random element in the sequence of elements of your scrollView. Basically, I solved this same thing for myself in one of my projects (free app "IJCAI11" in the appStore, there you can see at the work of a datePicker in the details of any chosen conference's day: there is applied the algorithm of infinite scrolling view, the limits I applied later only from design point of view). The scheme I use there is simple, though perhaps a bit weird (before reading ahead, note that in my case I see only one element of scrollView on the screen, when the scrollView is in nonscrolling state):

  1. I create the UIScrollView with 3 (in case you see more than 1 element at a time this can be like 5, 7, ..., 2N+1 according to your very case) labels;
  2. Make the second (central) label active.
  3. Assign proper value to all 3 (2N+1) labels. On this step your second (central) label will contain data of (will show) the default value.
  4. When user scrolls one step left/right (to the position M_pos), you do it in a standard way, since your neighboring to central labels contain correct data (M).
  5. Then you take this new active value (M) and apply it for your central label (this is gonna be behind the scene, therefore the user wont see this on the screen), then you recalculate ALL the other labels properly ( ..., M-1, M, M+1, ...), including your M_pos position(!).
  6. With "animated:NO" mode you shift your scrollView to your central position. In this case user doesn't see anything, when in fact his scrollView was moved from position M_pos to the central position. All neighboring labels are already recalculated and you are ready to repeat the point 4 any number of times you wish, making a strong feeling for user, that he works with the scrollView with a huge number of elements (whereas in practice your just work with 3 (2N+1) labels, changing their content after every movement).

A question - Is it possible to make some "selection indicator"?

If I understand this question correctly, then just consider the View/Subview thing and in particular the function addSubview of View class ;)

Hope this helps!

I'm not sure if I understood your question right, but did you already think of using a NSTimer to repeat events with a certain speed or during a certain period of time? (Pointing at your "round and round thing".)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM