I have a VC with a scrollview and pagecontrol implemented in it. It has three pages, which are all set up correctly and working fine. What I want to be able to do is have the VC load onto different pages depending on what button a user presses.
In the method the button calls I have
ViewController *vc = [[ViewController alloc] init];
vc.pageControl.currentPage = 2;
[self.navigationController pushViewController:vc animated:YES];
When the VC loads, it is loaded onto the correct page (as evidenced by the bubbles at the bottom of the page) but it is displaying the information from page[0]. If I start scrolling, it jumps back to page[0] no matter what I do.
My best guess is that I need to make the VC load to a specific x origin depending on what page I want to display, but I haven't been able to find anything related to this, so I'm quite lost.
Appreciate any help.
EDIT: Here is the code from the VC class. I didn't write this and it is my first time working with PageControl, so I'm trying to learn as I go.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.pagingEnabled = TRUE;
self.scrollView.showsVerticalScrollIndicator = NO;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.delegate = self;
firstPage = [[UIView alloc] init];
firstPage.tag = 0;
secondPage = [[UIView alloc] init];
secondPage.tag = 1;
thirdPage = [[UIView alloc] init];
thirdPage.tag = 2;
pages = [[NSArray alloc] initWithObjects:firstPage, secondPage, thirdPage, nil];
// Page Control
self.pageControl = [[UIPageControl alloc] init];
self.pageControl.numberOfPages = 3;
self.pageControl.currentPage = 0;
[self.view addSubview:self.scrollView];
[self.view addSubview:self.pageControl];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// First Page Setup
//
[self setupFirstPage];
// Second Page Setup
//
[self setupSecondPage];
// Third Page Setup
//
[self setupThirdPage];
// Frame everything
//
CGRect screenFrame = [[UIScreen mainScreen] applicationFrame];
CGRect navBarFrame = self.navigationController.navigationBar.frame;
self.scrollView.frame = CGRectMake(0, navBarFrame.size.height, 320, screenFrame.size.height - navBarFrame.size.height);
self.pageControl.frame = CGRectMake(0, screenFrame.size.height - 70, 320, 20);
firstPage.frame = CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height);
secondPage.frame = CGRectMake(320 * secondPage.tag, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height);
thirdPage.frame = CGRectMake(320 * thirdPage.tag, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height);
// Add Subviews
//
[self.scrollView addSubview:firstPage];
[self.scrollView addSubview:secondPage];
[self.scrollView addSubview:thirdPage];
self.scrollView.contentSize = CGSizeMake(320 * pages.count, self.scrollView.frame.size.height);
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
Try adding this function and calling it right after you set the page number:
- (void)pageSelectorChanged
{
CGRect frame = self.scrollView.frame;
frame.origin.x = frame.size.width * self.pageControl.currentPage;
frame.origin.y = 0;
[self.scrollView scrollRectToVisible:frame animated:NO];
}
Related
I'm a noob to Iphone development (3rd day in Xcode) and I am trying to implement pageControl and scrollview so users can swipe between various pages. I'm using this tutorial and I can't figure out how to load/switch views from nib files as opposed to just changing the background color of a view. Any help is greatly appreciated.
MY CODE
Modification of PageControlExampleViewController.m renamed NewsClass2
// Creates the color list the first time this method is invoked. Returns one color object from the list.
+ (UIColor *)pageControlColorWithIndex:(NSUInteger)index {
if (__pageControlColorList == nil) {
__pageControlColorList = [[NSArray alloc] initWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor magentaColor],
[UIColor blueColor], [UIColor orangeColor], [UIColor brownColor], [UIColor grayColor], nil];
}
// Mod the index by the list length to ensure access remains in bounds.
return [__pageControlColorList objectAtIndex:index % [__pageControlColorList count]];
}
//Changing views instead of colors, not working
+ (UIView *)pageControlViewWithIndex:(NSUInteger)index {
if (__pageControlViewrList == nil) {
__pageControlViewrList = [[NSArray alloc] initWithObjects:[[UIView alloc] initWithNibName:#"PageView" bundle:nil], [[UIView alloc] initWithNibName:#"PageView" bundle:nil], [[UIView alloc] initWithNibName:#"PageView" bundle:nil],
[[UIView alloc] initWithNibName:#"PageView" bundle:nil], [[UIView alloc] initWithNibName:#"PageView" bundle:nil], [[UIView alloc] initWithNibName:#"PageView" bundle:nil], [[UIView alloc] initWithNibName:#"PageView" bundle:nil], nil];
}
// Mod the index by the list length to ensure access remains in bounds.
return [__pageControlViewList objectAtIndex:index % [__pageControlViewList count]];
}
// Set the label and background color when the view has finished loading.
- (void)viewDidLoad {
pageNumberLabel.text = [NSString stringWithFormat:#"Page %d", pageNumber + 1];
self.view.backgroundColor = [NewsClass2 pageControlColorWithIndex:pageNumber];
//Setting View Not Working
self.view = [NewsClass2 pageControlViewWithIndex:pageNumber];
}
welcome to Objective C.
First of all you need to set delegate of scroll view like
//in .h file write
#interface ViewController : UIViewController<UIScrollViewDelegate>
// in viewDidLoad
self.scrollView.delegate = self;
then write in delegate method of UIScrollView write...
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
then make an IBAction of valueChange for pageControl like .....
- (IBAction)changePage:(id)sender
{
int page = self.pageControlHelp.currentPage;
CGRect frame = self.scrollViewHelp.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[self.scrollViewHelp scrollRectToVisible:frame animated:YES];
}
And you have done .......
If you have any confusion for this please feel free to ask......
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
scrollView.backgroundColor = [UIColor redColor];
scrollView.maximumZoomScale = 1.0;
scrollView.minimumZoomScale = 1.0;
scrollView.clipsToBounds = YES;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.pagingEnabled = YES;
self.view = scrollView;
pageControl = [[UIPageControl alloc] init];
pageControl.frame = CGRectMake(50, 350, 50, 50);
pageControl.numberOfPages = 3;
pageControl.currentPage = 0;
[self.view addSubview:pageControl];
I am new to iPhone software development. Please give me some code I could use here.
- (void)setupPage
{
UIView *blueView = [[UIView alloc] init];
blueView.frame = CGRectMake(0, 0, 640, 480);
blueView.backgroundColor = [UIColor whiteColor];
[scrollView addSubview:blueView];
self.pageControl.numberOfPages = 2;
[scrollView setContentSize:CGSizeMake(640, 0)];
}
- (void)scrollViewDidScroll:(UIScrollView *)_scrollView
{
if(pageControlIsChangingPage){
return;
}
CGFloat pageWidth = _scrollView.frame.size.width;
int page = floor((_scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
}
you can create array of UIViewControllers like bellow....
NSMutableArray *viewControllers;
and then just add the viewControllers or views with for loops like bellow...
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < 5; i++) {
[controllers addObject:yourViewControlls];// use different viewControls
}
self.viewControllers = controllers;
so here 5 viewConreoller are added in array and use it in PageViewController
for more info see this tutorial and example..
pagecontrol-example-in-iphone
I have 2 views are connected with NavigationController. Second view is scrollView with page controll. My main view has 1 UIButton. When pressing on it are obtained 3-4 seconds delay. There are 21 views in scrollView. And I have spurts when scrolling between view in scrollView. How can I reduce delay and remove spurts?
My viewDidLoad method:
-(void)viewDidLoad {
self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0.0f, 280.0f, 320.0f, 20.0f)];
[self.view addSubview:self.pageControl];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0f, 30.0f, 480.0f, 250.0f)];
[self.view addSubview:self.scrollView];
pageControlBeingUsed = NO;
NSInteger firstNumber = 1;
for (NSUInteger i = 0; i < 20; i++) {
BIDExercisePrototype *view = [[BIDExercisePrototype alloc] initWithNumber:firstNumber];
[self.viewsArray addObject:view];
firstNumber += 50;
}
for (NSUInteger i = 0; i < 20; i++) {
UIViewController *someController = [[UIViewController alloc] init];
someController = [self.viewsArray objectAtIndex:i];
someController.view.frame = CGRectMake(480.0f*i, 0.0f, 480.0f, 280.0f);
[self.scrollView addSubview:someController.view];
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * self.viewsArray.count, self.scrollView.frame.size.height);
self.pageControl.backgroundColor = [UIColor clearColor];
self.pageControl.currentPage = 0;
self.pageControl.numberOfPages = self.viewsArray.count;
self.scrollView.showsVerticalScrollIndicator = NO;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.pagingEnabled = YES;
self.scrollView.delegate = self;
[self.pageControl addTarget:self action:#selector(changePage) forControlEvents:UIControlEventValueChanged];
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
if (!pageControlBeingUsed) {
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
self.pageControl.currentPage = page;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlBeingUsed = NO;
}
- (void)changePage {
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];
pageControlBeingUsed = YES;
}
I think you should be able to follow the same practice for improving UITableView's scroll performance.
Do your drawing manually and have only one view in each cell.
Check out the following SO post which discusses multiple ways to improve scrolling performance by rendering your cells in specific ways.
Tricks for improving iPhone UITableView scrolling performance?
May I suggest you forget about recoding the wheel (so to speak) and use existing projects that have already solved the problems
#implementation MainViewController
#synthesize scrollView,imageView;
- (id) init {
if (self != nil) {
self.title = #"Evolution";
}
return self;}
- (void)viewDidLoad {
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDetected:)];
tapGesture.numberOfTapsRequired = 1;
tapGesture.numberOfTouchesRequired = 1;
scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
int numberOfImages = 32;
CGFloat currentX = 0.0f;
for (int i=1; i <= numberOfImages; i++) {
// create image
NSString *imageName = [NSString stringWithFormat:#"page-%d.jpg", i];
UIImage *image = [UIImage imageNamed:imageName];
imageView = [[UIImageView alloc] initWithImage:image];
// put image on correct position
CGRect rect = imageView.frame;
rect.origin.x = currentX;
imageView.frame = rect;
// update currentX
currentX +=454; //mageView.frame.size.width;
[scrollView addSubview:imageView];
[imageView release];
}
[scrollView addGestureRecognizer:tapGesture];
scrollView.contentSize = CGSizeMake(currentX, 800);
scrollView.pagingEnabled=YES;
scrollView.userInteractionEnabled = YES;
scrollView.maximumZoomScale = 15;
scrollView.minimumZoomScale = 0.5;
scrollView.bounces = NO;
scrollView.bouncesZoom = NO;
scrollView.delegate = self;
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[self.view addSubview:scrollView];
[scrollView release];
[super viewDidLoad];}
- (BOOL)shouldAutorotateToInterfaceOrientation(UIInterfaceOrientation)interfaceOrientation{
return YES;}
-(void)tapDetected:(UIGestureRecognizer*)recognizer{
ImageViewController *settings = [[ImageViewController alloc] init];
[self.navigationController pushViewController:settings animated:YES];
[settings release];}
#end
#implementation ImgScrollViewAppDelegate
#synthesize window;#synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application{
LogMethod();
// If you want the status bar to be hidden at launch use this:
// application.statusBarHidden = YES;
//
// To set the status bar as black, use the following:
// application.statusBarStyle = UIStatusBarStyleBlackOpaque;
// Create window
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// this helps in debugging, so that you know "exactly" where your views are placed;
// if you see "red", you are looking at the bare window, otherwise use black
// window.backgroundColor = [UIColor redColor];
viewController = [ [ MainViewController alloc ] init ];
navigationController = [ [ UINavigationController alloc ] initWithRootViewController: viewController ];
/* Anchor the view to the window */
[window addSubview:[navigationController view]];
/* Make the window key and visible */
[window makeKeyAndVisible];
}
#end
in above code i have problem that is when check it on simulator then rotate device left and right. But view not change and i want to change it. how i modify it?
In your view controller implementation there is a method - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation. If you want it to rotate to any orientation, make it return YES. If you only want it to autorotate to some orientations, add an if statement to check and return yes or no.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
UIScrollView. Any thoughts on implementing “infinite” scroll/zoom?
I've got an UIScrollView and in it different images(about 30). I'd like to make it possible, when user reaches the last image to show the first one after it and so on. And I want to implement the same feature with the first image(to go to the last one).
I'd like to loop the images smoothly that user won't even notice that he is making another loop.
What is the best way to achieve this?
Thanks.
I've just done this. I have an array of images to add to the scrollview so I first of all add the last one to the scrollview, then run through the array to add all the images and then after that, add the first one from the array again.
Have a look through this code:
#import "MainViewController.h"
#import "MainView.h"
#define WIDTH_OF_SCROLL_PAGE 320
#define HEIGHT_OF_SCROLL_PAGE 352
#define WIDTH_OF_IMAGE 320
#define HEIGHT_OF_IMAGE 352
#define LEFT_EDGE_OFSET 0
#implementation MainViewController
#synthesize scrollView, slideImages;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad {
scrollView = [[UIScrollView alloc] init];
CGRect scrollFrame;
scrollFrame.origin.x = 0;
scrollFrame.origin.y = 0;
scrollFrame.size.width = WIDTH_OF_SCROLL_PAGE;
scrollFrame.size.height = HEIGHT_OF_SCROLL_PAGE;
scrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
scrollView.bounces = YES;
scrollView.pagingEnabled = YES;
scrollView.delegate = self;
scrollView.userInteractionEnabled = YES;
slideImages = [[NSMutableArray alloc] init];
[slideImages addObject:#"welcome-small.jpg"];
[slideImages addObject:#"football-small.jpg"];
[slideImages addObject:#"dancing-small.jpg"];
[slideImages addObject:#"celebration-small.jpg"];
//add the last image first
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[slideImages objectAtIndex:([slideImages count]-1)]]];
imageView.frame = CGRectMake(LEFT_EDGE_OFSET, 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE);
[scrollView addSubview:imageView];
[imageView release];
for (int i = 0;i<[slideImages count];i++) {
//loop this bit
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[slideImages objectAtIndex:i]]];
imageView.frame = CGRectMake((WIDTH_OF_IMAGE * i) + LEFT_EDGE_OFSET + 320, 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE);
[scrollView addSubview:imageView];
[imageView release];
//
}
//add the first image at the end
imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[slideImages objectAtIndex:0]]];
imageView.frame = CGRectMake((WIDTH_OF_IMAGE * ([slideImages count] + 1)) + LEFT_EDGE_OFSET, 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE);
[scrollView addSubview:imageView];
[imageView release];
[scrollView setContentSize:CGSizeMake(WIDTH_OF_SCROLL_PAGE * ([slideImages count] + 2), HEIGHT_OF_IMAGE)];
[scrollView setContentOffset:CGPointMake(0, 0)];
[self.view addSubview:scrollView];
[self.scrollView scrollRectToVisible:CGRectMake(WIDTH_OF_IMAGE,0,WIDTH_OF_IMAGE,HEIGHT_OF_IMAGE) animated:NO];
[super viewDidLoad];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
int currentPage = floor((self.scrollView.contentOffset.x - self.scrollView.frame.size.width / ([slideImages count]+2)) / self.scrollView.frame.size.width) + 1;
if (currentPage==0) {
//go last but 1 page
[self.scrollView scrollRectToVisible:CGRectMake(WIDTH_OF_IMAGE * [slideImages count],0,WIDTH_OF_IMAGE,HEIGHT_OF_IMAGE) animated:NO];
} else if (currentPage==([slideImages count]+1)) {
[self.scrollView scrollRectToVisible:CGRectMake(WIDTH_OF_IMAGE,0,WIDTH_OF_IMAGE,HEIGHT_OF_IMAGE) animated:NO];
}
}
- (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)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[scrollView release];
[slideImages release];
[super dealloc];
}
#end
I then use scrollViewDidEndDecelerating to check where in the scroll the user is, and then jump them to the 2nd image or last but 1 image so they can scroll continuously... Sorry if I haven't explained it well - short of time! But this code is working fine for me on the device..
You can also have infinite scrolling without paging. Here is a great explanation at WWDC