how to make parallax demo with three tab like image give below - ios

How to make parallax demo with three tab like image given below in iOS make scrolling vertically.and click on tab multiple table scrolling Horizental.

Try using a UIScrollView with paging enabled. Then connect an IBAction to the buttons with a tag value to it. The tag value indicates which page the UIScrollView has to show. Make sure the UIScrollView direction is set to horizontal. In this example I'm only adding UIViews but this could be anything. UITableView, UIScrollView or UICollectionView you name it.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//Set number of pages
int numberOfPages = 3;
//Set properties scrollView
self.scrollView.pagingEnabled = true;
self.scrollView.contentSize = CGSizeMake((numberOfPages * self.scrollView.frame.size.width), self.scrollView.frame.size.height);
//Add pages
UIView *pageOne = [[UIView alloc] initWithFrame:CGRectMake((0 * self.scrollView.frame.size.width), 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
[pageOne setBackgroundColor:[UIColor yellowColor]];
[self.scrollView addSubview:pageOne];
UIView *pageTwo = [[UIView alloc] initWithFrame:CGRectMake((1 * self.scrollView.frame.size.width), 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
[pageTwo setBackgroundColor:[UIColor blueColor]];
[self.scrollView addSubview:pageTwo];
UIView *pageThree = [[UIView alloc] initWithFrame:CGRectMake((2 * self.scrollView.frame.size.width), 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
[pageThree setBackgroundColor:[UIColor redColor]];
[self.scrollView addSubview:pageThree];
}
- (IBAction)btnSelectPage:(id)sender; {
UIButton *btn = (UIButton *)sender;
[self.scrollView setContentOffset:CGPointMake((self.scrollView.frame.size.width * btn.tag), 0) animated:true];
}
And for the storyboard do something like this:
Don't forget to set the tag value of the button indicating what page you would like to show.

Related

UIScrollView is not scrolling even with setting contentSize

My UIScrollView isn't scrolling. (I'm trying to get it to scroll horizontally) I'm setting the contentSize to be (960, 300). I have set the framesize of the UIScrollView to be width:320 height:300 in the storyboard.
I have a container view inside the scroll view that has a width of 960 points.
At 320 points, I have a subview that has a background color of brown. When I scroll, I can see the brown subview, but it bounces back when I let go of the drag.
This is my viewDidLoad method:
- (void)viewDidLoad
[super viewDidLoad];
self.scrollView.scrollEnabled = YES;
[self.scrollView setFrame:CGRectMake(0,0,320,300)];
self.scrollView.contentSize = CGSizeMake(960, 300);
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectMake(320, 0, 320, 300)];
[subview1 setBackgroundColor:[UIColor brownColor]];
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 960, 300)];
[containerView addSubview:subview1];
[self.scrollView addSubview:containerView];
}
Here is a sample code for create a scroll view programmatically:
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 300)];
scrollView.backgroundColor = [UIColor redColor];
scrollView.scrollEnabled = YES;
scrollView.contentSize = CGSizeMake(960, 300);
[self.view addSubview:scrollView];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectMake(320, 0, 320, 300)];
[subview1 setBackgroundColor:[UIColor brownColor]];
UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 960, 300)];
containerView.backgroundColor = [UIColor greenColor];
[containerView addSubview:subview1];
[scrollView addSubview:containerView];
So, there is no issue in your code, but something wrong with your storyboard configure.
I have a few thoughts about what you are trying to accomplish. I don't know how old is your code, but today we have many better ways to work with scrollview and they don't include setting up the intrinsic size or fame.
Well, despite my doubt about the objective of the code, I tried to run it here, using storyboard, a single view, a default configured scrollView and the experiment went well, your code actually works, I think maybe you have some problem with your scrollView. I know this will sound weird but did you checked if the scrollView has the property "Scrolling Enabled" checked?
If you can give me more information about this issue, I can help you.

Page control on subview

I am creating a view with a subview for a tutorial screen.
I want the gray subview to be swipeable using the page control
I have implemented the example of http://www.appcoda.com/uipageviewcontroller-tutorial-intro/ but this works with whole ViewControllers and I want it to work with only the subview...
Does anyone have any idea how to implement the PageControl with the swipe gesture so that only the gray subview changes? Any good tutorial?
The grey area must be a UIScrollView with a content view containing each page of the tutorial. Set pagingEnabled to YES on your scroll view so that it will snap to each page when you scroll.
Then you need to attach an action to the page control using addTarget:action:forControlEvents: and pass UIControlEventValueChanged as the event. Then the action must be a method that tells the scroll view to move forward or back a page depending on whether the value of the page control increased or decreased. You can do this by changing the scroll view's content offset, or by telling it to scroll so that a particular rect is visible.
Finally, implement the delegate of the UIScrollView, and use the methods that tell when the scroll view stopped scrolling (you'll need a combination of the did end decelerating, did end dragging and possibly did end scrolling animation), and update the page control's value when the scroll view changes pages.
And that's all there is to it. If you need more details, read the documentation for UIScrollView, UIScrollViewDelegate and UIPageControl.
use UIView instead of ViewController
Here is a solution that works for me:
1) Create a scrollView and pageControl in your NIB or Storyboard
2) scrollView in ViewDidLoad
self.scrollView.backgroundColor = [UIColor clearColor];
self.scrollView.indicatorStyle = UIScrollViewIndicatorStyleBlack; //Scroll bar style
self.scrollView.showsHorizontalScrollIndicator = NO;
//dont forget to set delegate in .h file
[self.scrollView setDelegate:self];
self.scrollView.showsVerticalScrollIndicator = YES; //Close vertical scroll bar
self.scrollView.bounces = YES; //Cancel rebound effect
self.scrollView.pagingEnabled = YES; //Flat screen
self.scrollView.contentSize = CGSizeMake(640, 30);
3) create your views you want in the scrollView and add them in an Array
//For instance, you want 3 views
UIView *ViewOne = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
[ViewOne setBackgroundColor:[UIColor redColor]];
UIView *ViewTwo = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width+1, self.scrollView.frame.size.height)];
[ViewTwo setBackgroundColor:[UIColor greenColor]];
UIView *ViewThree = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width+2, self.scrollView.frame.size.height)];
[ViewThree setBackgroundColor:[UIColor blueColor]];
//add all views to array
NSMutableArray *viewsArray = [[NSMutableArray alloc] initWithObjects:ViewOne, ViewTwo, ViewThree, nil];
4) pageControl in ViewDidLoad
self.pageControl.numberOfPages = viewsArray.count;
self.pageControl.currentPage = 0;
self.pageControl.backgroundColor = [UIColor clearColor];
[self.pageControl setTintColor:[UIColor whiteColor]];
5) Add it all up
for(int i = 0; i < viewsArray.count; i++)
{
CGRect frame;
frame.origin.x = (self.scrollView.frame.size.width *i) + 10;
frame.origin.y = 0;
frame.size = CGSizeMake(self.scrollView.frame.size.width - 20, self.scrollView.frame.size.height);
NSLog(#"array: %#", [viewsArray objectAtIndex:i]);
UIView *view = [[UIView alloc] initWithFrame:frame];
view = [viewsArray objectAtIndex:i];
[self.scrollView addSubview:view];
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width*viewsArray.count, self.scrollView.frame.size.height);
}
6) Track the scrollView and update the pageControl (DONT FORGET THE SCROLLVIEW DELEGATE)
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat pageWidth = scrollView.frame.size.width;
//int page = floor((scrollView.contentOffset.x - pageWidth*0.3) / pageWidth) + 1);
self.pageControl.currentPage = (int)scrollView.contentOffset.x / (int)pageWidth;
NSLog(#"CURRENT PAGE %d", self.pageControl.currentPage);
}
This should do the trick.
PS. Sorry for all the magic numbers.

My UIView has a UIButton as one of it's subviews but not responding to events in objective-c

Here is my code. It has started to look crowded after an hour or 2 of trying to solve this issue. I've tried setting user interaction enabled to yes, I've tried just using a button alone and not making it the subview of another view.
Right now I have filterBar > filterBarContainer > filterButton.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.navigationController.navigationBar.userInteractionEnabled = YES;
self.view.userInteractionEnabled = YES;
// Create filter bar with specified dimensions
UIView *filterBar = [[UIView alloc] initWithFrame:CGRectMake(0, 42, self.view.frame.size.width, self.navigationController.navigationBar.frame.size.height)];
[filterBar setUserInteractionEnabled:YES];
// Make it a subview of navigation controller
[[[self navigationController] navigationBar] addSubview:filterBar];
[filterBar setBackgroundColor:[[UIColor whiteColor] colorWithAlphaComponent:0.9f]];
[filterBar setTag:1];
// Reusable vars
// CGFloat filterBarX = filterBar.frame.origin.x;
//CGFloat filterBarY = filterBar.frame.origin.y;
CGFloat filterBarHeight = filterBar.frame.size.height;
CGFloat filterBarWidth = filterBar.frame.size.width;
// Create centre filter button with specified dimensions
UIView *filterButtonContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 2, filterBarWidth / 2 - 30 , filterBarHeight - 10)];
[filterButtonContainer setUserInteractionEnabled:YES];
// Make it a subview of filter bar
[filterBar addSubview:filterButtonContainer];
[filterButtonContainer setBackgroundColor:[UIColor redColor]];
// Centre the button
[filterButtonContainer setCenter:[filterBar convertPoint:filterBar.center fromView:filterBar.superview]];
// Add button to filter button
UIButton *filterButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[filterButton setUserInteractionEnabled: YES];
[filterButton setFrame:CGRectMake(0, 0,40 , 20)];
[filterButton setTitle:#"test" forState:UIControlStateNormal];
[filterButtonContainer addSubview:filterButton];
[filterButton setBackgroundColor:[UIColor yellowColor]];
// self.filterButton = filterButton;
[filterButton addTarget:self action:#selector(filterButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
NSLog(#"dd");
filterButtonContainer.layer.borderColor = [UIColor blackColor].CGColor;
filterButtonContainer.layer.borderWidth = 1;
This is the method I'm trying to trigger.
- (void)filterButtonTapped:(UIButton *)sender
{
NSLog(#"filter button tapped");
UIActionSheet *filterOptions = [[UIActionSheet alloc] initWithTitle:#"Filter Garments"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Recommended", #"What's New", #"Price - High to Low", #"Price - Low to High", nil];
[filterOptions showInView:self.collectionView];
}
Most likely one of your parent views (superviews of your button) have a width or height that places the filter button outside of their area. The button is still displayed (if you don't define that the view should cut off subviews), but elements outside the view's area will not get any touch events. Check your superview's width and height.
You're adding filterBar as a subview of your navigationBar, but you're setting it's y-origin within navigationBar to 42. And then you're setting your filterButtonContainer's y-origin within the filterBar to 2. Assuming navigationBar's height is 44, most of the filterBar and the entirety of your filterButtonContainer and filterButton won't be within their navigationBar superview so the button wouldn't be selectable.
Edit: To make it selectable while keeping the positioning intact, I suggest adding the filter bar to self.view. For example, change:
[[[self navigationController] navigationBar] addSubview:filterBar];
to
[self.view addSubview:filterBar];

Choppy Paging UIScrollView Experience

I'm interested in implementing a paging UIScrollView experience, very similar to the current Twitter app, where there is a main paging UIScrollView (horizontal scrolling) at the top of the view hierarchy, and several other (vertical scrolling) UIScrollViews or UITableViews as the paging UIScrollView's subview.
I was taking reference from this WWDC video where they described how we could add a/several "zooming" scrollViews as a subview of a bigger "paging" scrollView.
In my current setup, I have:
A ViewController in storyboard with hierarchy as follows: View > ScrollView (contentScrollView) > Several subviews (UIImageViews, UIButtons and UILabels).
When that view is being loaded, I call a method setupPagingScrollView method in its viewDidAppear.
- (void)setupPagingScrollView
{
// Setup the PAGING UIScrollView
self.pagingScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 340, self.view.frame.size.height)];
self.pagingScrollView.contentSize = CGSizeMake(680, self.view.frame.size.height);
self.pagingScrollView.pagingEnabled = YES;
self.pagingScrollView.backgroundColor = [UIColor blackColor];
// Remove the CONTENT UIScrollView (from storyboard) from the view.
// Add the CONTENT UIScrollView (from storyboard), as a subview of the newly created PAGING UIScrollView
[self.contentScrollView removeFromSuperview];
[self.pagingScrollView addSubview:self.contentScrollView];
[self.view addSubview:self.pagingScrollView];
// Create the 2nd page, which is a UITableView
self.tableView = ({
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(340, 0, 320, self.view.frame.size.height) style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
tableView.backgroundColor = [UIColor whiteColor];
tableView.tableFooterView = [UIView new];
tableView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0);
tableView;
});
[self.pagingScrollView addSubview:self.tableView];
// UINavigationBar for the UITableView in the 2nd page.
self.likesCommentsNavBar = ({
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(340, 0, 320, 44)];
UINavigationItem *navItem = [[UINavigationItem alloc] init];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:#[#"Likes", #"Comments"]];
[segmentedControl addTarget:self action:#selector(toggleLikesCommentsWithSegmentedControl:) forControlEvents:UIControlEventValueChanged];
segmentedControl.selectedSegmentIndex = 0;
navItem.titleView = segmentedControl;
navBar.items = #[navItem];
navBar;
});
[self.pagingScrollView addSubview:self.likesCommentsNavBar];\
}
My intended end result would be something like the twitter application, just that instead of panning between 3 UITableViews, my first view would be a custom view with some images, labels, and buttons, and the 2nd and 3rd page would be UITableViews.
I have created a mockup of my intended result
Currently, I am able to get the result I want but I realize that there is some choppiness in the performance. Am I doing something wrong here by allocating memory to so many views or something?
Many thanks!
Incase the image loading on the main thread is the problem here, here is an easy way to load images on a background thread
UIImageView *imageView = [[UIImageView alloc] init]; // can be your IBOutlet or something instead
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
UIImage *image = [UIImage imageNamed:#"imageName"];
dispatch_sync(dispatch_get_main_queue(), ^{
imageView.image = image; //can add some fade in animation or something here too
});
});

How to enable zoom for two different UIScrollview in single UIView?

I am displaying two images on single view where both images must have zoom functionality.My page height is around 1000 pixels and images must be display on top and bottom of page. For that I have added two different scroll view and added image views on scroll views.
Now Zoom is working properly for second image .But first image is getting displayed in top left corner of scroll view once zoomed out. It seems there are two images.
Here is the delegate method i am using:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return [[scrollView subviews] objectAtIndex:0];
}
Is there anything i am missing ? or is this not really possible to enable zoom when there are two scroll views for single page.
Here is the code its working for enable zoom when there are two scroll views for single page.
//Create First ImageView
image1 =[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 220)];
image1.image = [UIImage imageNamed:#"image1.png"];
image1.contentMode = UIViewContentModeScaleToFill;
//Create and Set Values for Scrollview 1
scroll1 =[[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 220)];
scroll1.contentSize = image1.frame.size;
[scroll1 setMinimumZoomScale:1.0];
[scroll1 setMaximumZoomScale:4.0];
scroll1.delegate = self;
scroll1.clipsToBounds = YES;
scroll1.tag =0;
[scroll1 addSubview:image1];
image1.userInteractionEnabled =YES;
scroll1.zoomScale = 1;
[self.view addSubview:scroll1];
Second Scrollview and ImageView
// Create Second ImageView
image2 =[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 260)];
image2.image = [UIImage imageNamed:#"image2.png"];
image2.contentMode = UIViewContentModeScaleToFill;
// Create Second ScrollView
scroll2 =[[UIScrollView alloc] initWithFrame:CGRectMake(0, 220, 320, 260)];
scroll2.contentSize = image2.frame.size;
[scroll2 setMinimumZoomScale:1.0];
[scroll2 setMaximumZoomScale:4.0];
scroll2.delegate = self;
scroll2.clipsToBounds = YES;
scroll2.tag =1;
[scroll2 addSubview:image2];
image2.userInteractionEnabled =YES;
scroll2.zoomScale = 1;
[self.view addSubview:scroll2];
This will help you, since it is already working for me.
Delegate method as follow:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
if (scrollView.tag ==0) {
return image1;
}
else return image2;
}

Resources