Reputation: 1966
I would like to emulate the swipe to left to show next picture seen in the photos app, among other places so that the new picture slides in from right to left using animation.
However, in my case, the view has more than one photo. It has a caption as well.
I am able to do this without animation by just updating the photo and text upon swipe. This just changes the photo and caption on screen, however, without the right to left animation technique.
Is there a way to show the old view moving to the left while the new updated view moves in from the right.
The following moves the view to the left but renders the screen black as nothing is put in its place.
//In handleSwipe called by gesture recognizer
CGRect topFrame = self.view.frame;
topFrame.origin.x = -320;
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.view.frame = topFrame; _myImage=newImage;
_mycaption=newcaption;} completion:^(BOOL finished){ }];
Thanks for any suggestions.
Edit: The view in question is a detail view that you get to from a tableview through a segue. It currently already uses a scrollview for vertical scrolling as the content can exceed a single screen in the vertical dimension.
I have found a way to get the old photo and caption to move left and the new to come in from right using a completion block, however, it is less than satisfactory, because there is a gap between the two actions when the screen is black. This seems endemic to completion approach because new image does not start to move until old image has completed moving.
- (IBAction)swipedLeft:(id)sender
{
CGRect initialViewFrame = self.view.frame;
CGRect movedToLeftViewFrame = CGRectMake(initialViewFrame.origin.x - 375, initialViewFrame.origin.y, initialViewFrame.size.width, initialViewFrame.size.height);
CGRect movedToRightViewFrame = CGRectMake(initialViewFrame.origin.x + 375, initialViewFrame.origin.y, initialViewFrame.size.width, initialViewFrame.size.height);
[UIView animateWithDuration:0.1
animations:^{self.view.frame = movedToLeftViewFrame;
//above moves old image out of view.
}
completion:^(BOOL finished)
{
self.view.frame = movedToRightViewFrame;
[self loadNextItem];//changes pic and text.
[UIView animateWithDuration:0.1
animations:^{self.view.frame = initialViewFrame;
//moves new one in
}
completion:nil];
}];
}
Upvotes: 1
Views: 1116
Reputation: 361
It's ScrollView+PageControl I hope it can help you.
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.delegate =self;
self.scrollView.translatesAutoresizingMaskIntoConstraints =NO;
self.scrollView.pagingEnabled =YES;
self.scrollView.contentSize =CGSizeMake(ViewWidth*VIewCount, ViewHeight);
[self.view addSubview:self.scrollView];
self.pageControl = [[UIPageControl alloc] init];
self. pageControl.translatesAutoresizingMaskIntoConstraints =NO;
[self.view addSubview:self.pageControl];
self. pageControl.numberOfPages = VIewCount;
self.pageControl.currentPage = 0;
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0f
constant:0.0f]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[self.scrollView(width)]"
options:0
metrics:@{@"width":@(ViewWidth)}
views:NSDictionaryOfVariableBindings(self.scrollView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[self.scrollView(height)]"
options:0
metrics:@{@"height":@(HEIGHT_VIEW)}
views:NSDictionaryOfVariableBindings(self.scrollView)]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_scrollView]-5-[pageControl(15)]"
options:NSLayoutFormatAlignAllCenterX
metrics:nil
views:NSDictionaryOfVariableBindings(self.scrollView, self.pageControl)]];
//[imgArr addObject:[UIImage imageNamed:...]];
for (NSInteger index = 0; index<ViewCount; index++) {
UIImageView *addSubview = [[UIImageView alloc] initWithFrame:CGRectMake(index*ViewWidth, 0, ViewWidth, ViewHeight)];
// addSubView.image = [imgArr objectAtIndex:index];
[self.scrollView addSubview:addSubview];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
NSInteger currentOffset = scrollView.contentOffset.x;
NSInteger index = currentOffset / ViewWidth;
if (currentOffset % ViewWidth == 0) {
pageControl.currentPage = index;
}
}
Upvotes: 0
Reputation: 385650
Three ways to build this using existing components:
UIPageViewController
(see DuncanC's answer).
UICollectionView
with pagingEnabled
set to true. Use a full-screen-sized cell and a UICollectionViewFlowLayout
with scrollDirection
set to horizontal.
UICollectionView
as above, but instead of setting pagingEnabled
to true, implement scrollViewWillEndDragging:withVelocity:targetContentOffset:
in your delegate. This allows you to have a gutter between each cell while still having each cell fill the screen. See this answer.
Upvotes: 2
Reputation: 131418
I suggest using a UIPageViewController
, and manage each image/set of images as a separate view controller.
A page view controller supports either a page curl style transition or a slide transition. You'd want the slide transition.
Upvotes: 4