I'm attempting a parallax effect with a UIScrollView whereby there will be an UIImageView and UILabel per 'page', and as the user scrolls through the pages, the UIImageView will disappear off of the current page at a faster rate than the UILabel, while the next UIImageView and UILabel appear.
My code is working perfectly when on the first page as the amplifier is not taken into account, thus not working on any other page; the UIImageView is not centered horizontally within the page, which it should be.
Please can you tell me where I'm going wrong?
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint offset = scrollView.contentOffset;
NSInteger currentPage = floorf(offset.x / CGRectGetWidth(self.view.frame));
if (currentPage >= 0 && currentPage < CINNumberOfWalkthroughs) {
NSInteger lastPage = self.pageControl.currentPage;
self.pageControl.currentPage = currentPage;
float imageViewAmplifier = offset.x / scrollView.contentSize.width;
UIImageView *imageView = self.imageViews[currentPage];
float w = CGRectGetWidth(self.view.frame);
float a = CGRectGetWidth(imageView.frame);
imageView.center = CGPointMake((currentPage * w) + ((w + a) / 2) + (offset.x * imageViewAmplifier), imageView.center.y);
}
}
I used the following calculation to determine the center position of each of the UIImageViews, and then add a portion of the offset to add the moving effect.
I managed to fix the issue by simplifying things - I have the tendency to overcomplicate everything which made this task a lot more difficult than it needed to be.
Instead of working out the current center of the imageView
and performing the translation by transforming the center point, I used a simple CGAffineTransformMakeTranslation()
which effectively deals with all of this for me. All I had to do from there was work out the actual offset from the origin of the page, and then fix the amplifier, which was corrected by working out the ration between the actual offset and the content size of the scroll view. My working solution can be found below:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint offset = scrollView.contentOffset;
NSInteger currentPage = floorf(offset.x / CGRectGetWidth(self.view.frame));
if (currentPage >= 0 && currentPage < CINNumberOfWalkthroughs) {
self.pageControl.currentPage = currentPage;
UIImageView *imageView = self.imageViews[currentPage];
float multiplier = -1 * (offset.x / scrollView.contentSize.width);
float w = CGRectGetWidth(self.view.frame);
imageView.transform = CGAffineTransformMakeTranslation((offset.x - currentPage * w) * multiplier, 0);
UILabel *instructionLabel = self.instructionLabels[currentPage];
instructionLabel.transform = CGAffineTransformMakeTranslation((offset.x - currentPage * w) * (multiplier - 0.4), 0);
}
}