3

Basically, I want to have an app with only one view that has an image on it. I want to be able to swipe left or right and have the first image go out of the view and the second image to come in. The images are the same and I want it to look like they are connected (like scrolling down a rope where the pattern just repeats, but it looks like a constant scroll). I need it to be able to change the image or restart after a series of swipes. I know that I need to turn pagination ON in the UIScrollView, but I am new to iOS and am having trouble.

Ultimately, I want to have the iPhone vibrate every so-and-so swipes (and restart the pattern).

I'm sure that there are a lot of ways to do this (i.e. a TableView) so feel free to just point me in the direction of some references if the answer is tedious to explain.

Thanks!

FOLLOW UP:

I found an Apple example that did very nearly what I wanted to do. I made a lot of adjustments to it, but I'm banging my head against a wall trying to get the images to cycle. Here is what I think is the offending code, but I'm not sure what the solution is, as the ScrollView is functional, it just doesn't reset the center to the current view. Any ideas?

    - (void)layoutScrollImages
{
        UIImageView *view = nil;
        NSArray *subviews = [scrollView1 subviews];

    // reposition all image subviews in a horizontal serial fashion
    CGFloat curXLoc = 0;
    for (view in subviews)
    {
        if ([view isKindOfClass:[UIImageView class]] && view.tag > 0)
        {
            CGRect frame = view.frame;
            frame.origin = CGPointMake(curXLoc, 0);
            view.frame = frame;

            curXLoc += (kScrollObjWidth);
        }
    }

    // set the content size so it can be scrollable
    [scrollView1 setContentSize:CGSizeMake((kNumImages * kScrollObjWidth), [scrollView1 bounds].size.height)];

}
Sneagan
  • 43
  • 1
  • 1
  • 5

2 Answers2

7

I'd just use a UIScrollView. Set the contentWidth to be 3 times the width/height of the view (for 3 pages) and set the contentOffset to be the center 'page' (view.bounds.size.width or view.bounds.size.height depending on whether you're scrolling horizontally/vertically respectively) . You'll need to setup a delegate for the UIScrollView (probably the view controller) and implement - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView. This will be called when the scroll view has finished decelerating. Once it has finished decelerating, reset the contentOffset back to the center view. This should give the impression of an infinite scroll. You can also set a counter to increment in the scrollViewDidEndDecelerating method to increment the counter or initiate the vibration.

You shouldn't need to keep repositioning the images. Just set the images once in the scrollView:

//Horizontal arrangement
UIImage *image = [UIImage imageNamed:@"nameOfImage.png"];
UIImageView *imageView1 = [[UIImageView alloc] initWithImage:image];
UIImageView *imageView2 = [[UIImageView alloc] initWithImage:image];
UIImageView *imageView3 = [[UIImageView alloc] initWithImage:image];
NSArray *imageViews = [NSArray arrayWithObjects:imageView1, imageView2, imageView3];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[self.view addSubview: scrollView]; //This code assumes it's in a UIViewController
CGRect cRect = scrollView.bounds;
UIImageView *cView;
for (int i = 0; i < imageViews.count; i++){
    cView = [imageViews objectAtIndex:i];
    cView.frame = cRect;
    [scrollView addSubview:cView];
    cRect.origin.x += cRect.size.width;
}
scrollView.contentSize = CGSizeMake(cRect.origin.x, scrollView.bounds.size.height);
scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0); //should be the center page in a 3 page setup

So the images are setup, you don't need to mess with them anymore. Just reset the contentOffset when the scroll views stops (note: you need to make sure you're the delegate of the scroll view or you'll not receive the message when the scroll view stops):

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0);
}

Please forgive any typos. I wrote it out by hand.

Abdul Saleem
  • 10,098
  • 5
  • 45
  • 45
Aaron Hayman
  • 8,492
  • 2
  • 36
  • 63
  • I found an Apple example that did very nearly what I wanted to do. I made a lot of adjustments to it, but I'm banging my head against a wall trying to get the images to cycle. Here is what I think is the offending code, but I'm not sure what the solution is, as the ScrollView is functional, it just doesn't reset the center to the current view. Any ideas? Code is above. – Sneagan Feb 25 '12 at 17:41
  • This looks great. Once I figure out what a sentinel is an why NSArray is missing one it looks like it should work (it seems from my searches that the sentinel issue has to do with subclassing the NSArray. I'm sure that the fact that I'm having an issue with it is indicative of my experience level and is not your doing). I really appreciate the help you've given me with this. After finishing 2 code books I've just decided that learning this way is best and you've been a great help. – Sneagan Feb 26 '12 at 00:19
  • Looks like the imageViews need to be wrapped in @"" and followed by nil. Got rid of the Sentinel issue, but still throwing an exception. Investigating. – Sneagan Feb 26 '12 at 00:57
  • Why are you subclassing NSArray? Usually, I've found it better to add a category to NSArray/NSMutableArray than do any kind of subclassing. – Aaron Hayman Feb 26 '12 at 01:02
  • I think I misdiagnosed the issue. Once I placed the @"" around the imageViews the problem disappeared. The only issue now is a crash caused by an exception that I can't seem to identify. – Sneagan Feb 26 '12 at 01:11
  • *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString setFrame:]: unrecognized selector sent to instance 0x4550' – Sneagan Feb 26 '12 at 01:14
  • I'm sorry, I think I understand what you're doing now. You misunderstood my code. It was just supposed to be an example... imageView1/2/3 are supposed to be of class UIImageView, I'll change my code to make is clearer. I was demonstrating is as an example, but you need to put UIImageViews (views that hold images) in the array and place those views in the scrollview. My code assumed a certain familiarity with objective-c. Again sorry. – Aaron Hayman Feb 26 '12 at 13:44
  • No apology necessary! I suspected something like that and made them NSObjects and then put the objects in the array to no avail. You're clarification is extremely helpful. Thanks for helping out a newb! – Sneagan Feb 26 '12 at 17:48
  • 2
    You can also add scrollview.pagingEnabled=YES; Then you do not need the delegate scrollviewDidEndDecelerating: – doozMen Jun 08 '12 at 08:12
1

Look on cocoacontrols.com for a custom photo album view. As for the vibration, this code snippet vibrates the phone (make sure you link to and #import <AudioToolbox/AudioToolbox.h>):

 AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
alicanbatur
  • 2,172
  • 1
  • 28
  • 36
CodaFi
  • 43,043
  • 8
  • 107
  • 153