Below is the code of ModelController.m:
- (id)init
{
self = [super init];
if (self) {
// Create the data model.
DataHandler *handler = [DataHandler defaultDataHandler];
[handler syncData];
NSInteger tempTotal=1;//[[DataHandler defaultDataHandler] getTotalContents];
NSMutableDictionary *favs=[Settings getSetting:kFavList];
if(favs!=nil){
tempTotal=[favs count]+1;
}
NSInteger TotalItems=tempTotal;//tempTotal>=6?tempTotal:6;
NSInteger PageSize=6;
NSInteger PageNo= (TotalItems/PageSize);
if(TotalItems%PageSize!=0){
PageNo++;
}
self.TotalPage=PageNo;
NSInteger i=0,temp=PageSize;
self.pageArray=[[NSMutableDictionary alloc] initWithCapacity:PageNo];
for (i=0; i<PageNo; i++) {
temp=(PageNo==i+1 && TotalItems%PageSize!=0)? TotalItems%PageSize:PageSize;
[self.pageArray setObject:[NSString stringWithFormat:#"%d",temp] forKey:[NSString stringWithFormat:#"%d",i+1]];
}
//NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//_pageData = [[dateFormatter monthSymbols] copy];
self.pageData=[self.pageArray allKeys];
}
return self;
}
- (HomeViewController *)viewControllerAtIndex:(NSUInteger)index {
NSLog(#"viewControllerAtIndex is called..");
// Return the data view controller for the given index.
if (([self.pageData count] == 0) || (index >= [self.pageData count])) {
return nil;
}
// Create a new view controller and pass suitable data.
HomeViewController *homeViewController = nil;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
homeViewController = [[[HomeViewController alloc] initWithNibName:#"HomeViewController_iPhone" bundle:nil] autorelease];
} else {
homeViewController = [[[HomeViewController alloc] initWithNibName:#"HomeViewController_iPad" bundle:nil] autorelease];
}
homeViewController.dataObject = [self.pageData objectAtIndex:index];
homeViewController.PageItemsCount= [[self.pageArray valueForKey:[NSString stringWithFormat:#"%d",index+1]] integerValue];
homeViewController.TotalPage=self.TotalPage;
homeViewController.CurrentPage=index+1;
return homeViewController;
}
- (NSUInteger)indexOfViewController:(HomeViewController *)viewController
{
// Return the index of the given data view controller.
// For simplicity, this implementation uses a static array of model objects and the view controller stores the model object; you can therefore use the model object to identify the index.
return viewController.CurrentPage-1;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:(HomeViewController *)viewController];
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:(HomeViewController *)viewController];
if (index == NSNotFound) {
return nil;
}
index++;
if (index == [self.pageData count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
This is working fine when I swipe the screen, but I also want to change screen on any button tap of main view page (in this case it's homeViewController.m), as it's code is very lengthy I didn't post code here.
can anyone tell me how to achieve this?
Thanks
Ashish
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.80];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:self.view cache:NO];
[UIView commitAnimations];
//Addd this line on click event of button action
You could simply try and animate the view transform like this (for a vertical flip):
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut
animations:^(void) {
view.transform = CGAffineTransformMakeScale(1, -1);
}
completion:nil];
Thanks
Related
Can we change the spine location without changing orientations. Like for some views it is set to max and for some views it should be mid. Is it possible to active this functionality.
This is the code i am using, but don't know what to modify in it so that without changing orientation i can set spine location to max and set one page mode rather than two page mode. Actually is started with two page mode when app runs but later it requires to move to single page mode, that is not getting possible, it gives error that you are providing one view but than two required.
Can anyone guide for this.
-(id)initWithViewControllers:(NSMutableArray *)Controllers
{
self = [super initWithNibName:nil bundle:nil];
if(self)
{
self.VControllers = Controllers;
pageController = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation: UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageController.view.frame = CGRectMake(12.0f, 10.0f, 748.0f, 985.0f);
self.pageController.delegate = self;
self.pageController.dataSource = self;
[self.pageController setViewControllers:[NSArray arrayWithObject:[VControllers objectAtIndex:0] ] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:^(BOOL finished)
{
}];
[self addChildViewController:self.pageController];
[self.view addSubview:self.pageController.view];
check=YES;
}
return self;
}
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
if(UIInterfaceOrientationIsPortrait(orientation))
{
//Set the array with only 1 view controller
UIViewController *currentViewController = [self.pageController.viewControllers objectAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:currentViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
//Important- Set the doubleSided property to NO.
self.pageController.doubleSided = NO;
//Return the spine location
return UIPageViewControllerSpineLocationMax;
}
else
{
NSArray *viewControllers = nil;
exampleViewController *currentViewController = [self.pageController.viewControllers objectAtIndex:0];
NSUInteger currentIndex = [self.VControllers indexOfObject:currentViewController];
if(currentIndex == 0 || currentIndex %2 == 0)
{
UIViewController *nextViewController = [self pageViewController:self.pageController viewControllerAfterViewController:currentViewController];
viewControllers = [NSArray arrayWithObjects:currentViewController, nextViewController, nil];
}
else
{
UIViewController *previousViewController = [self pageViewController:self.pageController viewControllerBeforeViewController:currentViewController];
viewControllers = [NSArray arrayWithObjects:previousViewController, currentViewController, nil];
}
//Now, set the viewControllers property of UIPageViewController
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
return UIPageViewControllerSpineLocationMid;
}
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
int index = [self.VControllers indexOfObject:viewController];
i=index;
//[self checkViewControllers];
if (index - 1 >= 0)
{
ind = index;
return [self.VControllers objectAtIndex:index - 1];
}
return nil;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
int index = [self.VControllers indexOfObject:viewController];
i=index;
if (index + 1 < [self.VControllers count])
{
ind = index;
return [self.VControllers objectAtIndex:index + 1];
}
if (ind1 + 1 < [self.VControllers count])
{
ind = index;
return [self.VControllers objectAtIndex:index + 1];
}
return nil;
}
If you want to change the spine location after the UIPageViewController is already initialized I think you may need to create a new one, with the new spine location, and replace the old one with it.
I guess the current implementation only considers setting the spine location while initializing or when changing orientations.
You may open a bug for Apple so they implement that in the future.
I am using UIPageViewController to show two view controllers at a time. After showing a couple of such views, i want to show single view controllers without changing orientation, it is fixed to landscape. I am making in iPad.
Below is the code i am using for this:
-(id)initWithViewControllers:(NSMutableArray *)Controllers
{
self = [super initWithNibName:nil bundle:nil];
if(self)
{
self.VControllers = Controllers;
pageController = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation: UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageController.view.frame = CGRectMake(12.0f, 10.0f, 748.0f, 985.0f);
self.pageController.delegate = self;
self.pageController.dataSource = self;
[self.pageController setViewControllers:[NSArray arrayWithObject:[VControllers objectAtIndex:0] ] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:^(BOOL finished)
{
}];
[self addChildViewController:self.pageController];
[self.view addSubview:self.pageController.view];
}
return self;
}
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
if(UIInterfaceOrientationIsPortrait(orientation))
{
//Set the array with only 1 view controller
UIViewController *currentViewController = [self.pageController.viewControllers objectAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:currentViewController];
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
//Important- Set the doubleSided property to NO.
self.pageController.doubleSided = NO;
//Return the spine location
return UIPageViewControllerSpineLocationMin;
}
else
{
NSArray *viewControllers = nil;
exampleViewController *currentViewController = [self.pageController.viewControllers objectAtIndex:0];
NSUInteger currentIndex = [self.VControllers indexOfObject:currentViewController];
if(currentIndex == 0 || currentIndex %2 == 0)
{
UIViewController *nextViewController = [self pageViewController:self.pageController viewControllerAfterViewController:currentViewController];
viewControllers = [NSArray arrayWithObjects:currentViewController, nextViewController, nil];
}
else
{
UIViewController *previousViewController = [self pageViewController:self.pageController viewControllerBeforeViewController:currentViewController];
viewControllers = [NSArray arrayWithObjects:previousViewController, currentViewController, nil];
}
//Now, set the viewControllers property of UIPageViewController
[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
return UIPageViewControllerSpineLocationMid;
}
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
int index = [self.VControllers indexOfObject:viewController];
//[self checkViewControllers];
if (index - 1 >= 0)
{
ind = index;
return [self.VControllers objectAtIndex:index - 1];
}
ind = index;
return nil;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
int index = [self.VControllers indexOfObject:viewController];
//[self checkViewControllers];
if (index + 1 < [self.VControllers count])
{
ind = index;
return [self.VControllers objectAtIndex:index + 1];
}
ind = index;
return nil;
}
What i need is to show the single view controllers after shows double views a couple of time. This functionality i am unable to active yet. Can anyone guide for this .
Thanks in advance.
I have problem in my project in the search bar code.
Inside the app I added a search bar to my table view at run time. The search worked fine only 2 times!
If I tried to search for third time the search bar did not allow me to enter any input, and returns me to the home page of the app.
// staffArr Array to store the staff objects
// tableData store the data that will display in table
- (void)viewDidLoad {
[super viewDidLoad];
tableData = [[NSMutableArray alloc] init];
[tableData addObjectsFromArray:staffArr];
self.disableViewOverlay = [[UIView alloc]
initWithFrame:CGRectMake(0.0f,44.0f,320.0f,416.0f)];
self.disableViewOverlay.backgroundColor=[UIColor blackColor];
self.disableViewOverlay.alpha = 0;
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[self searchBar:searchBar activate:YES];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
searchBar.text=#"";
[self searchBar:searchBar activate:NO];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self.tableData removeAllObjects];
if([searchBar.text isEqualToString:#""]|| searchBar.text==nil){
[staffTAB reloadData];
return;}
for(NSInteger i=0;i<staffArr.count;i++)
{
staff *sta = (staff *)[self.staffArr objectAtIndex:i];
NSString *name =sta.staff_name;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSRange r = [name rangeOfString:searchBar.text];
if(r.location != NSNotFound)
{
if(r.location== 0)// checking only the start of the names.
{
[tableData addObject:sta];
}
}
[pool release];
}
[self searchBar:searchBar activate:NO];
[self.staffTAB reloadData];
}
- (void)searchBar:(UISearchBar *)searchBar activate:(BOOL) active
{
self.staffTAB.allowsSelection = !active;
self.staffTAB.scrollEnabled = !active;
if (!active)
{
[disableViewOverlay removeFromSuperview];
[searchBar resignFirstResponder];
}
else
{
self.disableViewOverlay.alpha = 0;
[self.view addSubview:self.disableViewOverlay];
[UIView beginAnimations:#"FadeIn" context:nil];
[UIView setAnimationDuration:0.5];
self.disableViewOverlay.alpha = 0.6;
[UIView commitAnimations];
NSIndexPath *selected = [self.staffTAB indexPathForSelectedRow];
if (selected) {
[self.staffTAB deselectRowAtIndexPath:selected animated:NO];
}
}
[searchBar setShowsCancelButton:active animated:YES];
}
Thanks in advance
I want to create scrollView with pagecontrol programmatically. How can i do that?
#pragma mark -
#pragma mark loadGalleryView
-(void) loadGalleryView{
galleryArr = [memberDic objectForKey:#"arrKey"];
if ([galleryArr count]%5 != 0)
{
noOfPages = ([galleryArr count]/5)+1;
}
else
{
noOfPages = [galleryArr count]/5;
}
viewControllers = [[NSMutableArray alloc] init];
for (int i=0; i<noOfPages; i++)
{
[viewControllers addObject:[NSNull null]];
}
[galleryScrollView setPagingEnabled:TRUE];
[galleryScrollView setContentSize:CGSizeMake(self.view.frame.size.width* noOfPages,69.0f)];
[galleryScrollView setShowsHorizontalScrollIndicator:FALSE];
[galleryScrollView setShowsVerticalScrollIndicator:FALSE];
[galleryScrollView setScrollsToTop:FALSE];
[galleryScrollView setDelegate:self];
[pageControl setNumberOfPages:noOfPages];
[pageControl setCurrentPage:0];
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
}
//-----------------Load scroll View----------------------------------
-(void) loadScrollViewWithPage:(int) page{
if (page < 0)
{
return;
}
if (page >= noOfPages)
{
return;
}
GalleryViewController *givc = [viewControllers objectAtIndex:page];
if ((NSNull *)givc == [NSNull null])
{
givc = [[GalleryViewController alloc] initWithPageNumber:page];
givc.imageArr = [galleryArr retain];
[viewControllers replaceObjectAtIndex:page withObject:givc];
[givc release];
}
if (nil == givc.view.superview)
{
CGRect frame = self.view.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0.0f;
givc.view.frame = frame;
[galleryScrollView addSubview:givc.view];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
// We don't want a "feedback loop" between the UIPageControl and the scroll delegate in
// which a scroll event generated from the user hitting the page control triggers updates from
// the delegate method. We use a boolean to disable the delegate logic when the page control is used.
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = galleryScrollView.frame.size.width;
int page = floor((galleryScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// A possible optimization would be to unload the views+controllers which are no longer visible
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
isPageControlUsed = NO;
}
in gallary View Controller in .m file
- (void)viewDidLoad {
[super viewDidLoad];
float x = 7.0f;
for (int i = (pageNumber*5); i<(pageNumber+1)*5; i++)
{
if (i<[imageArr count])
{
NSString *url = [imageArr objectAtIndex:i];
MyImageView *imgView = [[MyImageView alloc] initWithFrame:CGRectMake(x, 7.5f, 55.0f, 55.0f)];
[imgView addImageFrom:url];
[self.view addSubview:imgView];
[imgView release];
x = x+62.5f;
}
}
}
-(id)initWithPageNumber:(int) page{
if (self = [super initWithNibName:#"GalleryViewController" bundle:nil])
{
pageNumber = page;
}
return self;
}
Ok, so I am trying to a pagescrollView with two views each with a different view controller so I can work on each different view. I got apple's sample code and it seems that they created a lot of different view "lazily as they said" how can this code be altered so that I can have the first page be one view controller and the second page be another view controller?
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// view controllers are created lazily
// in the meantime, load the array with placeholders which will be replaced on demand
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < kNumberOfPages; i++) {
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
// a page is the width of the scroll view
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.delegate = self;
pageControl.numberOfPages = kNumberOfPages;
pageControl.currentPage = 0;
// pages are created on demand
// load the visible page
// load the page on either side to avoid flashes when the user starts scrolling
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];
}
- (void)loadScrollViewWithPage:(int)page {
if (page < 0) return;
if (page >= kNumberOfPages) return;
// replace the placeholder if necessary
MyViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
controller = [[MyViewController alloc] initWithPageNumber:page];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
- (void)scrollViewDidScroll:(UIScrollView *)sender {
// We don't want a "feedback loop" between the UIPageControl and the scroll delegate in
// which a scroll event generated from the user hitting the page control triggers updates from
// the delegate method. We use a boolean to disable the delegate logic when the page control is used.
if (pageControlUsed) {
// do nothing - the scroll was initiated from the page control, not the user dragging
return;
}
// Switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = scrollView.frame.size.width;
int page = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
pageControl.currentPage = page;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// A possible optimization would be to unload the views+controllers which are no longer visible
}
// At the end of scroll animation, reset the boolean used when scrolls originate from the UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
pageControlUsed = NO;
}
- (IBAction)changePage:(id)sender {
int page = pageControl.currentPage;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:page - 1];
[self loadScrollViewWithPage:page];
[self loadScrollViewWithPage:page + 1];
// update the scroll view to the appropriate page
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
// Set the boolean used when scrolls originate from the UIPageControl. See scrollViewDidScroll: above.
pageControlUsed = YES;
}
Thanks if anyone knows how to do this.
To load the pages with different view controllers all you have to change is this segment of code
MyViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{ controller = [[MyViewController alloc] initWithPageNumber:page];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
to initialize each view controller to the one you want instead of the same one each time, so the code would look something like
if(page==0)
{
MyViewControllerZero *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{ controller = [[MyViewControllerZero alloc] initWithPageNumber:page];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
}
if(page==1)
{
MyViewControllerOne *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{ controller = [[MyViewControllerOne alloc] initWithPageNumber:page];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
}
//and so on ...
This is the Correct Code!!!
- (void)loadScrollViewWithPage:(int)page {
if (page < 0) return;
if (page >= kNumberOfPages) return;
// replace the placeholder if necessary
if (page == 0){
MyViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
controller = [[MyViewController alloc] initWithPageNumber:page];
[viewControllers replaceObjectAtIndex:page withObject:controller];
}
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
if (page == 1){
PageOne *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null]) {
controller = [[PageOne alloc] initWithPageNumber:page];
[viewControllers replaceObjectAtIndex:page withObject:controller];
}
if (nil == controller.view.superview) {
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
// add the controller's view to the scroll view
}
}
THX For the first answewr she open my mind!!!