I am making a simple slideshow view within my app. I'd like to link my UIPageControl to my UIScrollView. This shouldn't be too difficult, but I haven't been able to find a simple solution anywhere. Below is my code.
HelpViewController.h
#import <UIKit/UIKit.h>
#interface HelpViewController : UIViewController{
}
#end
HelpViewController.m
#import "HelpViewController.h"
#interface HelpViewController ()
#end
#implementation HelpViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect scrollViewFrame = CGRectMake(0, 62, 320, 404);
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
[self.view addSubview:scrollView];
CGSize scrollViewContentSize = CGSizeMake(640, 404);
[scrollView setContentSize:scrollViewContentSize];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(200, 200, 50, 21)];
[label setText:#"Hello"];
[scrollView addSubview:label];
[scrollView setPagingEnabled:YES];
scrollView.showsHorizontalScrollIndicator = NO;
UIPageControl *pageControl = [[UIPageControl alloc] init];
pageControl.frame = CGRectMake(110,5,100,100);
pageControl.numberOfPages = 2;
pageControl.currentPage = 0;
[self.view addSubview:pageControl];
pageControl.backgroundColor = [UIColor redColor];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Maybe this works for you
Don't forget to set the UIScrollView's delegate = self (or wherever you have the selector below).
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageWidth = self.scrollView.frame.size.width; // you need to have a **iVar** with getter for scrollView
float fractionalPage = self.scrollView.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
self.pageControl.currentPage = page; // you need to have a **iVar** with getter for pageControl
}
For your code it then would be:
.h file
#import <UIKit/UIKit.h>
#interface HelpViewController : UIViewController{
}
#property (nonatomic, retain) UIScrollView *scrollView;
#property (nonatomic, retain) UIPageControl * pageControl;
#end
.m file
#import "HelpViewController.h"
#interface HelpViewController ()
#end
#implementation HelpViewController
#synthesize scrollView=scrollView_;
#synthesize pageControl=pageControl_;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect scrollViewFrame = CGRectMake(0, 62, 320, 404);
self.scrollView = [[[UIScrollView alloc] initWithFrame:scrollViewFrame] autorelease];
self.scrollView.delegate = self;
[self.view addSubview:self.scrollView];
CGSize scrollViewContentSize = CGSizeMake(640, 404);
[self.scrollView setContentSize:scrollViewContentSize];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(200, 200, 50, 21)];
[label setText:#"Hello"];
[self.scrollView addSubview:label];
[self.scrollView setPagingEnabled:YES];
self.scrollView.showsHorizontalScrollIndicator = NO;
self.pageControl = [[[UIPageControl alloc] init] autorelease];
self.pageControl.frame = CGRectMake(110,5,100,100);
self.pageControl.numberOfPages = 2;
self.pageControl.currentPage = 0;
[self.view addSubview:self.pageControl];
pageControl.backgroundColor = [UIColor redColor];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageWidth = self.scrollView.frame.size.width;
float fractionalPage = self.scrollView.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
self.pageControl.currentPage = page;
}
#end
This is actually quite simple to setup. Firstly you need to create the scroll view and page control. Make sure you implement UIScrollViewDelegate in the interface of the class.
UIScrollView * scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * 3, scrollView.frame.size.height);
scrollView.delegate = self;
UIPageControl * pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 90, scrollView.frame.size.width, 20)];
pageControl.numberOfPages = scrollView.contentSize.width/scrollView.frame.size.width;
[pageControl addTarget:self action:#selector(changePage:) forControlEvents:UIControlEventValueChanged];
Then you need to add the following two methods:
- (IBAction)changePage:(id)sender {
CGFloat x = pageControl.currentPage * scrollView.frame.size.width;
[scrollView setContentOffset:CGPointMake(x, 0) animated:YES];
}
-(void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
NSInteger pageNumber = roundf(scrollView.contentOffset.x / (scrollView.frame.size.width));
pageControl.currentPage = pageNumber;
}
These methods add the required communication between the page control and the scroll view.
Following code will work for Swift:
func addScrollView() {
let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
let numberOfPages: CGFloat = 4
scrollView.contentSize = CGSize(width: scrollView.frame.width * numberOfPages, height: scrollView.frame.height * numberOfPages)
scrollView.delegate = self
scrollView.isPagingEnabled = true
let pageControl = UIPageControl(frame: CGRect(x: 0, y: scrollView.frame.height - 37, width: scrollView.frame.width, height: 37))
pageControl.numberOfPages = Int(numberOfPages)
pageControl.currentPage = 0
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let value = scrollView.contentOffset.x / scrollView.frame.size.width
pageControl.currentPage = Int(round(value))
}
to get exact page index without rounding off the value simply put the pagecontrol.currentpage in the scrollViewDidEndDecelerating delegate method of scroll view.This works for me!
All these answers are great but I'd like to offer an alternative solution, using ReactiveCocoa!
The following code makes an assumption that you have a property called scrollView and one called pageControl.
[RACObserve(self.scrollView, contentOffset)
subscribeNext:^(NSValue* value){
CGPoint offset = [value CGPointValue];
CGFloat fractional = offset.x/self.scrollView.width;
[self.pageControl setCurrentPage:lroundf(fractional)];
}];
All that's going on here is you're observing change on the contentOffset property of the scrollView and calculating the page index on every next event (i.e. every time the property value changes).
The only downside of this is that you have to unbox the CGPoint but on the upside there's no UIScrollViewDelegate code needed at all!
Related
I placed a scrollview in storyboard ,i enabled paging also ,i made outlet for scrollview, i added 4 uiviews programmatically.Now i need paging with that 4 uiview in horizontally .Please help me to do ...
Thanks in advance
Here is my code
- (void)scrollingView
{
UIView *pageView1 = [[UIView alloc]init];
pageView1.frame = CGRectMake(0,0,self.scrollView.frame.size.width,self.scrollView.frame.size.height);
pageView1.backgroundColor = [UIColor blueColor];
[self.scrollView addSubview:pageView1];
UIView *pageView2 = [[UIView alloc]init];
pageview2.frame = CGRectMake(0,0,self.scrollView.frame.size,width,self.scrollView.frame.size.height);
pageView2.backgroundColor =[UIColor GrayColor];
[self.scrollView addSubview:pageView2];
}
xPosition = 0;
for (int i = 0; i<3; i++)
{
scrollView.clipsToBounds = YES;
//Views
UIView *views = [[UIView alloc]initWithFrame:CGRectMake(xPosition, 0, selfView.frame.size.width, scrollView.frame.size.height)];
views.clipsToBounds = YES;
[arrayOfViews addObject:views];
xPosition += selfView.frame.size.width;
[scrollView addSubview:views];
}
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * arrayOfViews.count, scrollView.frame.size.height);
and implement scrollview delegate method
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat pageWidth = self.scrollView.frame.size.width;
float fractionalPage = self.scrollView.contentOffset.x / pageWidth;
NSInteger page = lround(fractionalPage);
self.pageCnt.currentPage = page;
}
-(void)viewDidLayoutSubviews
{
UIImage *image1=[UIImage imageNamed:#"1.jpeg"];
UIImage *image2=[UIImage imageNamed:#"2.jpeg"];
UIImage *image3=[UIImage imageNamed:#"7.jpeg"];
UIImage *image4=[UIImage imageNamed:#"6.jpeg"];
// UIImage *image5=[[UIImage alloc]init];
NSArray *imagesArray=[[NSArray alloc]initWithObjects:image1,image2,image3,image4,nil];
for (int i=0; i<=3; i++) {
UIImageView *imgView=[[UIImageView alloc]init];
imgView.backgroundColor=[UIColor grayColor];
imgView.contentMode=UIViewContentModeScaleToFill;
imgView.alpha=0.5f;
imgView.frame=CGRectMake(i*self.scrollViewSlider.bounds.size.width, 0, self.scrollViewSlider.bounds.size.width, self.scrollViewSlider.bounds.size.height);
[imgView setImage:imagesArray[i]];
[self.scrollViewSlider addSubview:imgView];
}
self.scrollViewSlider.pagingEnabled=TRUE;
[self.scrollViewSlider setContentSize:CGSizeMake(imagesArray.count * self.scrollViewSlider.bounds.size.width, self.scrollViewSlider.bounds.size.height)];
}
- (void) scrollViewDidEndDecelerating: (UIScrollView *) __unused scrollView
{
CGFloat pageWidth = self.scView.frame.size.width;
self.pageControl.currentPage = (self.scView.contentOffset.x + pageWidth / 2) / pageWidth;
}
Try this u will get it is working
Header file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UIScrollViewDelegate>
#property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
#property (weak, nonatomic) IBOutlet UIScrollView *scView;
#end
Implementation :
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)viewDidLayoutSubviews
{
NSArray *imagesArray=[NSArray arrayWithObjects:
[UIColor colorWithRed:246/255.0 green:155/255.0 blue:0/255.0 alpha:1],
[UIColor colorWithRed:129/255.0 green:195/255.0 blue:29/255.0 alpha:1],
[UIColor colorWithRed:62/255.0 green:173/255.0 blue:219/255.0 alpha:1],
[UIColor colorWithRed:229/255.0 green:66/255.0 blue:115/255.0 alpha:1],
[UIColor colorWithRed:148/255.0 green:141/255.0 blue:139/255.0 alpha:1],nil];
for (int i=0; i<imagesArray.count; i++) {
UIView *containerView=[[UIView alloc]init ];
//containerView.backgroundColor=[UIColor redColor]
containerView.backgroundColor=imagesArray[i % imagesArray.count];
containerView.contentMode=UIViewContentModeScaleToFill;
containerView.alpha=0.5f;
containerView.frame=CGRectMake(i*self.scView.bounds.size.width, 0, self.scView.bounds.size.width, self.scView.bounds.size.height);
//[imgView setImage:imagesArray[i]];
[self.scView addSubview:containerView];
}
self.scView.pagingEnabled=TRUE;
NSLog(#"%ld",imagesArray.count);
NSLog(#"%ld",imagesArray.count);
[self.scView setContentSize:CGSizeMake(imagesArray.count * self.scView.bounds.size.width, self.scView.bounds.size.height)];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) scrollViewDidEndDecelerating: (UIScrollView *) __unused scrollView
{
CGFloat pageWidth = self.scView.frame.size.width;
self.pageControl.currentPage = (self.scView.contentOffset.x + pageWidth / 2) / pageWidth;
NSLog(#"%f",pageWidth);
}
I am trying to do a simple scroll, but the views do not move after a touch, I am not sure why, the scrollview should handle the gesture, but something might be missing. Would someone know where?
Here is the code : I create a small horizontal scroll view, with some views inside. The views appear well, I am testing it on a device for the touch :
- (void)viewDidLoad {
[super viewDidLoad];
//horizontal scroll view
HorizScroll *ho = [[HorizScroll alloc] initWithFrame:CGRectMake(0, 0, 500, 100)];
for ( int i=0; i<3; i++){
MyView* mv = [[MyView alloc] init];
[ho addSubview:mv];
}
//ho.zoomScale = 0.3f;
[self.view addSubview:ho];
}
#implementation HorizScroll
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
}
return self;
}
-(void)addSubview:(UIView *)view{
[super addSubview:view];
NSUInteger numSubviews = self.subviews.count;
[view setFrame:CGRectMake(CGRectGetWidth(view.bounds)*(numSubviews),
0,
CGRectGetWidth(view.bounds),
CGRectGetHeight(view.bounds) )];
[self setContentSize:CGSizeMake(CGRectGetWidth(view.bounds)*(numSubviews),
CGRectGetHeight(view.bounds) )];
}
#implementation MyView
-(int)getRandomNumberBetween:(int)from to:(int)pto {
return (int)(from + arc4random() % (pto-from+1));
}
-(instancetype)init{
if ( self = [super init] ){
CGFloat red = [self getRandomNumberBetween:1 to:255];
self.backgroundColor = [UIColor colorWithRed:red/256.0
green:[self getRandomNumberBetween:1 to:255]/256.0
blue:[self getRandomNumberBetween:1 to:255]/256.0
alpha:1.0];
}
return self;
}
-(instancetype)initWithFrame:(CGRect)frame{
if ( self = [super initWithFrame:frame] ){
self.frame = CGRectMake(counterX, 0, 100, 100);
counterX += 50;
}
return self;
}
You need to set contentSize of scrollview to be larger than its frame size. so add this line after [self.view addSubview:ho].
ho.contentSize = CGSizeMake(501.f, 100.f);
or before [self.view addSubview:ho] and comment out the line:
[self setContentSize:CGSizeMake(CGRectGetWidth(view.bounds)*(numSubviews),
CGRectGetHeight(view.bounds))];
which is not necessary since you can set it after all subviews are added.
after read some other cuestions about it i've tried:
on ViewController.m
DelegateScrollView ScrollView;
-(void)viewDidLoad
{
[super viewDidLoad];
ScrollView = [[DelegateScrollView alloc] initWithFrame:CGRectMake(0,- self.view.frame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
ScrollView.delegate = ScrollView;
ScrollView.scrollEnabled = YES;
ScrollView.backgroundColor = [UIColor blackColor ];
ScrollView.maximumZoomScale = 5.0f;
ScrollView.minimumZoomScale = 1.0f;
[self.view addSubview:ScrollView];
[ScrollView setZoomScale:2 animated:YES];
}
DelegateScrollView.h:
#interface ChildDelegateScrollView : UIScrollView <UIScrollViewDelegate>
#end
and zoom never happends also i've tried this in ViewController.h: #interface ViewController : UIViewController <UIScrollViewDelegate> then set delegate like this ScrollView.delegate = self; and not work, how is the way to set correctly a delegate to a ScrollView?
This line from the UIScrollView class reference seems to be relevant:
For zooming and panning to work, the delegate must implement both viewForZoomingInScrollView: and scrollViewDidEndZooming:withView:atScale:
I was able to get a UILabel on a UIScrollView to zoom using this UIViewController code:
#import "ViewController.h"
#interface ViewController () <UIScrollViewDelegate> {
UIScrollView *_scrollView;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height)];
scrollView.delegate = self;
scrollView.scrollEnabled = YES;
scrollView.backgroundColor = [UIColor blackColor];
scrollView.maximumZoomScale = 5.0f;
scrollView.minimumZoomScale = 1.0f;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width, scrollView.frame.size.height);
[self.view addSubview:scrollView];
_scrollView = scrollView;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50.0, 50.0, 100.0, 25.0)];
label.backgroundColor = [UIColor grayColor];
label.textAlignment = NSTextAlignmentCenter;
label.text = #"Test";
[_scrollView addSubview:label];
}
- (void)viewDidAppear:(BOOL)animated
{
[_scrollView setZoomScale:4.0 animated:YES];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return _scrollView.subviews.firstObject;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
}
#end
I've edited this question a few times, but can still not get my images to center inside a uiview. I want them to be able to rotate like the photos app and display the correct size when a user brings them up. Here is what I'm working with:
In my PhotoViewController.h
#import <UIKit/UIKit.h>
#protocol PhotoViewControllerDelegate <NSObject>
- (void)toggleChromeDisplay;
#end
#interface PhotoViewController : UIViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate>
#property (nonatomic, strong) UIImage *photo;
#property (nonatomic) NSUInteger num;
//Delegate
#property (nonatomic, strong) id<PhotoViewControllerDelegate> photoViewControllerDelegate;
#property (nonatomic, strong) UIImageView *photoImgView;
#property (nonatomic, strong) UIScrollView *scrollView;
#end
In my PhotoViewController.m:
#import "PhotoViewController.h"
#interface PhotoViewController ()
#end
#implementation PhotoViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
//todo
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect screenBounds = self.view.bounds;
//scroll view
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, screenBounds.size.width, screenBounds.size.height)];
_scrollView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
_scrollView.pagingEnabled = NO;
_scrollView.scrollEnabled = YES;
[_scrollView setBackgroundColor:[UIColor blueColor]];
//Zoom Properties
_scrollView.maximumZoomScale = 6.0;
_scrollView.minimumZoomScale = 1.0;
_scrollView.bouncesZoom = YES;
_scrollView.delegate = self;
_scrollView.zoomScale = 1.0;
_scrollView.contentSize = _photoImgView.bounds.size;
[_scrollView setShowsHorizontalScrollIndicator:NO];
[_scrollView setShowsVerticalScrollIndicator:NO];
[self photoBounds];
[self.view addSubview: _scrollView];
//Add the UIImageView
_photoImgView = [[UIImageView alloc] initWithImage:_photo];
_photoImgView.image = _photo;
_photoImgView.clipsToBounds = YES;
_photoImgView.contentMode = UIViewContentModeScaleAspectFit;
_photoImgView.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin);
[_photoImgView setUserInteractionEnabled:YES];
[_scrollView addSubview: _photoImgView];
//Set up Gesture Recognizer
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
UITapGestureRecognizer *dTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dTapGestureCaptured:)];
dTap.numberOfTapsRequired = 2;
[singleTap requireGestureRecognizerToFail:dTap];
//Gesture Methods
[self.scrollView addGestureRecognizer:singleTap];
[self.scrollView addGestureRecognizer : dTap];
}
- (void)photoBounds
{
UIInterfaceOrientation statusbar = [[UIApplication sharedApplication] statusBarOrientation];
CGSize photoBounds = _photo.size;
CGSize scrollBounds = self.view.bounds.size;
CGRect frameToCenter = [_photoImgView frame];
float newHeight = (scrollBounds.width / photoBounds.width) * photoBounds.height;
float newWidth = (scrollBounds.height / photoBounds.height) * photoBounds.width;
float yDist = fabsf(scrollBounds.height - newHeight) / 2;
float xDist = fabsf(scrollBounds.width - newWidth) / 2;
//Width Larger
if (photoBounds.width >=photoBounds.height) {
NSLog(#"portrait width");
_photoImgView.frame = CGRectMake(0, 0, scrollBounds.width, newHeight);
frameToCenter.origin.y = yDist;
}
//Height Larger
else if (photoBounds.height > photoBounds.width) {
NSLog(#"portrait height");
_photoImgView.frame = CGRectMake(0, 0, newWidth, scrollBounds.height);
frameToCenter.origin.x = xDist;
}
//Square
else {
NSLog(#"portrait square");
if ((statusbar == 1) || (statusbar == 2)) {
_photoImgView.frame = CGRectMake(0, 0, scrollBounds.width, newHeight);
frameToCenter.origin.y = yDist;
} else {
_photoImgView.frame = CGRectMake(0, 0, newWidth, scrollBounds.height);
frameToCenter.origin.x = xDist;
}
}
}
//Rotation Magic
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
//later
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self photoBounds];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
//
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
//Zoom Ability
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.photoImgView;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
NSLog(#"scale %f", scale);
NSLog(#"done zooming");
}
//Touches Control
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
//CGPoint touchPoint=[gesture locationInView:_scrollView];
NSLog(#"touched");
NSLog(#"single touch");
[self performSelector:#selector(callingHome) withObject:nil afterDelay:0];
}
- (void)dTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
NSLog(#"double touched");
}
- (void)panGestureCaptured:(UIPanGestureRecognizer *)gesture
{
NSLog(#"pan gesture");
}
- (void)callingHome {}
#end
The overall issue is that I can not get my picture to display correctly and be able to zoom on just it, no space around it and It needs to be the correct dimensions on load. I've been struggling with it for a few days.
Any help?
I have resolved a similar problem using a really simple subclass of UIScrollView of my own. You can take a look at it here - https://gist.github.com/ShadeApps/5a29e1cea3e1dc3df8c8. Works like charm for me.
That's how you init it:
scrollViewMain.delegate = self;
scrollViewMain.minimumZoomScale = 1.0;
scrollViewMain.maximumZoomScale = 3.0;
scrollViewMain.contentSize = imageViewMain.frame.size;
scrollViewMain.backgroundColor = [UIColor blackColor];
scrollViewMain.tileContainerView = imageViewMain;
There is awesome blog post about this problem from Peter Steinberger: http://petersteinberger.com/blog/2013/how-to-center-uiscrollview/
I am trying to add a page control to my scroll view, and have followed numerous web tutorials, the majority which use the same code as this tutorial. However, once I place the code into my project, even with me making changes to the code to try to make it work, it just doesn't. I have managed to make the code work for when the page control is pressed, however it just won't work for the page scrolling. My issue is similar to this, although the answers are of no help. Here is my code:
MainViewController.h
#interface MainViewController : UIViewController
{
UIScrollView *svCollegeMain;
UIScrollView *svCollegePage;
UIPageControl *pcCollege;
UIView *viewP1;
}
#property (nonatomic, retain) IBOutlet UIScrollView* svCollegeMain;
#property (nonatomic, retain) IBOutlet UIScrollView* svCollegePage;
#property (nonatomic, retain) IBOutlet UIPageControl * pcCollege;
- (IBAction)changePage;
#end
and MainViewController.m
#implementation MainViewController
#synthesize svCollegeMain, svCollegePage, pcCollege;
- (void)viewDidLoad
{
[super viewDidLoad];
self.svCollegeMain.contentSize = CGSizeMake(960, 332);
self.svCollegePage.contentSize = CGSizeMake(320, 500);
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)scrollViewDidScroll:(UIScrollView *)sender
{
CGFloat pageWidth = 320;
int page = floor((svCollegeMain.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pcCollege.currentPage = page;
}
- (IBAction)changePage
{
CGRect frame;
frame.origin.x = self.svCollegeMain.frame.size.width * self.pcCollege.currentPage;
frame.origin.y = 0;
frame.size = self.svCollegeMain.frame.size;
[self.svCollegeMain scrollRectToVisible:frame animated:YES];
}
#pragma mark - View lifecycle
- (void)viewDidUnload
{
[super viewDidUnload];
self.svCollegeMain = nil;
self.svCollegePage = nil;
self.pcCollege = nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Just incase this makes any difference, my view is set out with a view, then a main scroll view and page control within this view, another view and scroll view (next to each other) within the main scroll view, and finally a final view in the second scroll view (all in IB, did not want too much code), and everything is linked up in IB.
I notice that your MainViewController doesn't declare itself as implementing UIScrollViewDelegate, so I also assume that you've forgotten to set it up as the delegate for the scroll view in IB (otherwise it wouldn't compile).
Since it has no delegate defined, the scroll view won't be calling your scrollViewDidScroll function.
Tim
Try this
HeaderFile:
#interface DemoPageControlViewController : UIViewController <UIScrollViewDelegate>
{
IBOutlet UIScrollView *scrollView;
IBOutlet UIPageControl *pageControl;
BOOL pageControlUsed;
NSMutableArray *imageArray;
int pageNumber;
}
#property (nonatomic, retain) UIScrollView *scrollView;
#property (nonatomic, retain) UIPageControl *pageControl;
#property (nonatomic, retain) NSMutableArray *imageArray;
- (IBAction) changePage:(id)sender;
Implementation File:
#import "DemoPageControlViewController.h"
#implementation DemoPageControlViewController
#synthesize pageControl, scrollView, imageArray;
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
imageArray = [[NSMutableArray alloc]init];
[imageArray addObject:#"small_one.png"];
[imageArray addObject:#"small_two.png"];
[imageArray addObject:#"small_three.png"];
[imageArray addObject:#"small_four.png"];
// add the last image to first
UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed: [imageArray objectAtIndex:([imageArray count] -1)]]];
imageView.frame = CGRectMake(0, 0, scrollView.frame.size.width, scrollView.frame.size.height);
[self.scrollView addSubview:imageView];
[imageView release];
for(int i = 0; i < imageArray.count; i++)
{
UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:[imageArray objectAtIndex:i]]];
imageView.frame = CGRectMake((scrollView.frame.size.width * i ) + 320 , 0, scrollView.frame.size.width, scrollView.frame.size.height);
[self.scrollView addSubview:imageView];
[imageView release];
}
// add the first image to last
imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:[imageArray objectAtIndex:0]]];
imageView.frame = CGRectMake(scrollView.frame.size.width * ([imageArray count]+1), 0, scrollView.frame.size.width, scrollView.frame.size.height);
[self.scrollView addSubview:imageView];
[imageView release];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * ([imageArray count]+ 2), self.scrollView.frame.size.height);
[scrollView setContentOffset:CGPointMake(0, 0)];
[self.view addSubview:scrollView];
[self.scrollView scrollRectToVisible:CGRectMake(scrollView.frame.size.width,0,scrollView.frame.size.width,scrollView.frame.size.height) animated:NO];
}
- (IBAction)changePage :(id)sender
{
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage ;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
[self.scrollView scrollRectToVisible:frame animated:YES];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
pageControlUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
//pageControlUsed = NO;
NSLog(#"%f", self.scrollView.contentOffset.x);
CGFloat pageWidth = self.scrollView.frame.size.width;
//pageNumber = floor((self.scrollView.contentOffset.x - pageWidth / ([imageArray count]+2)) / pageWidth) + 1 ;
pageNumber = self.scrollView.contentOffset.x / pageWidth;
if(pageNumber == 0)
{
[self.scrollView scrollRectToVisible:CGRectMake((self.scrollView.frame.size.width * [imageArray count]), 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height) animated:NO];
pageNumber = [imageArray count];
//self.pageControl.currentPage = pageNumber;
}
else if(pageNumber == ([imageArray count]+1))
{
[self.scrollView scrollRectToVisible:CGRectMake(self.scrollView.frame.size.width, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height) animated:NO];
pageNumber = 1;
//self.pageControl.currentPage = pageNumber;
}
self.pageControl.currentPage = pageNumber - 1;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
}
This Code works fine. Try this