Page Control Question - iphone

I am trying to figure out how to add a page control to my view correctly. I have a keypad currently on the view along with a picker, but I want to separate the keypad and picker.
So I want to swipe to page two, and load a different view which essentially just has a picker. Page one will just have a keypad.
I can't find an example of a page control that switches to two separate views. I looked at the apple example PageControl, but that did not solve my issues.
Any help, suggestions are much appreciated.

You're not going to be able to do this with the native keypad - it doesn't belong to any one view, and so cannot be "paged" in the manner you describe.
As for a couple of hints as far as implementing paging: what you'll want to do is make a UIScrollView, set it's contentSize to be two pages wide (or more if you prefer), and set pagingEnabled to YES. Then add your pages as subviews. Note that the UIPageControl does not itself implement paging - it is an indicator only.
Some basic sample code (untested) assuming horizontal paging:
- (void) initPagesForScrollview:(UIScrollView*) scrollView
{
CGRect pageFrame = CGRectMake(0, 0, scrollView.bounds.size.width,
scrollView.bounds.size.height);
scrollView.contentSize = CGSizeMake(pageFrame.size.width * 2,
pageFrame.size.height)
scrollView.pagingEnabled = YES;
UIView* page1 = ...
page1.frame = pageFrame;
[scrollView addSubview:page1];
UIView* page2 = ...
pageFrame.origin.x += pageFrame.size.width;
page2.frame = pageFrame;
[scrollView addSubview:page2];
}
Note the origin of page 2 shifted to the right to make it begin off screen.
You can also do most of this through interface builder, but that's a little more difficult to demonstrate here... Feel free to ask if there's something specific you need.

Related

what is the similar of linear layout in ios

I have many components in my view controller, and I want to combine them in a single object to scroll them together, what is the procedure to do it (like linearlayout in android) but I need it in IOS.
iOS9 introduced something similar to LinearLayout: UiStackView
See this video from WWDC 2015: https://developer.apple.com/videos/wwdc/2015/?id=218
Apple not provide linear container
but you can use XHFLinearView at github
Usage Example:
XHFLinearView *linearView=[[XHFLinearView alloc]initWithFrame:self.view.bounds];
[self.view addSubview:linearView];
//init linear view content views
[linearView.itemSource addObject:XHFLinearViewUnitMake(someView, XHFMarginMake(0, 0, 0, 0))];
//force layout linear view
[linearView needLayout];
//insert a view with animation
[linearView insertItem:someView margin:XHFMarginMake(0, 0, 0, 0) atIndex:0 withAnimation:XHFLinearItemAnimationFade];
//replace a view with animation
[linearView replaceItem:someView withNewItem:newView withAnimation:XHFLinearItemAnimationFade];
//resize a view with animation
someView.frame=xxx;
[linearView needLayoutForItem:someView];
//remove a view with animation
[linearView removeItemByIndex:0 withAnimation:XHFLinearItemAnimationFade];
LayoutManager
First of all, what you're looking for is a declarative API for layouts. I guess a lot of people that comming from other languages/platforms miss that. iOS just has some other approaches like layout constraints or autoresizing. However this does not fit all the use cases.
Layout libraries
I would suggest to take a look into some libraries existing at CocoaPods. Its easy to install and kick off with it.
I'd like to mention CSLinearLayoutView which is quite easy. Even I am maintainer of a smaller project MKLayoutLibrary which is available via CocoaPods as well. Thats a more compressive one which also provides a linear-, stack- and a simple flow-layout.
Clean solution
However, if you really want to go very deeply into the topic of layouts I recommend playing with UICollectionView and its layout customisation possibilities.
Consider that declarative solutions does not work for a huge amount of items or endless scrolling layouts. If you want to do so, take a further look into UICollectionView custom layouts.
I just wrote a widget called AutoLinearLayoutView which can be checked out from Github.
It's totally based on Auto-layout and supporting iOS 7+. According to your requirement, the example project perfectly demonstrates a dozen of widgets being wrapped by linear layout view, and the linear layout view being placed in UIScrollView.
Linear Layout in Android = Stack View in iOS
Android:
orientation: Horizontal, Vertical
iOS:
Horizontal Stack View, Vertical Stack View in iOS
More:
Recycler View in Android = Table View in iOS
There is no such layout available in iOS. Each component you add on the view will be displayed based on it's frame (not in sequential manner).
For doing this stuff you can use UIScrollView.
Check this tutorial How to use UIScrollView
You'll likely have to do something a bit more manual with iOS. You can add all your views to a UIScrollView, however you'll have to set the contentSize of the UIScrollView appropriately. Essentially, for N items, the scroll view width will be:
scrollView.contentSize = CGSizeMake(N * itemWidth + (N - 1) * itemPadding, itemHeight);
Then, you'll need to set the frame of each UIView so that its x-coordinate is appropriate, and add it to the UIScrollView:
for (int i = 0; i < views.count; i++) {
UIView *view = [views objectAtIndex:i];
view.frame = CGRectMake(i * itemWidth + i * itemPadding,
view.frame.origin.y,
view.frame.size.width,
view.frame.size.height);
[scrollView addSubview:view];
}
If you want something more complicated than a simple linear layout, have a look at UICollectionView.
Every component as uiview in ios. so you can put every components into UIView like
[containerView addSubView:YourComponent1];
[containerView addSubView:YourComponent2];
[containerView addSubView:YourComponent3];
then you can add this into your UIScrollView

How to load a view that is larger than a specific area in Xcode 4?

I"m relatively new to iOS development, as you can likely tell, and would like to display about 600 pixels worth of content (in height) on the screen. Just to give you a bit of context, I'm building a tab bar application, so what I'm assuming would be a UIScrollView cannot be defined in the App Delegate. Primarily, what I'm confused about is changing the size of the view and then defining the behaviour of the UIScrollView. I've looked everywhere, but they are all tutorials for < Xcode 4, plus none of them use the View Controller to define a scroll view. Is there a specific IBAction that would only allow the view to scroll up and down, not left and right. Any help would be appreciated.
Once you define the contentSize and assign a subview to the UIScrollView you should be able to scroll automatically.
To make sure you have vertical and horizontal scrolling you could do this -
[scrollview setBounces:YES];
[scrollview setShowsVerticalScrollIndicator:YES];
[scrollview setShowsHorizontalScrollIndicator:YES];
[scrollview setScrollEnabled:YES];
[scrollview setUserInteractionEnabled:YES];
If you want to add double-tap to zoom etc. you could do that too in similar way...

UIScrollView with multiple pages visible or smaller page sizes

I'm trying to make a paging UIScrollView display multiple pages at the same time, in effect, making the page size smaller than the UIScrollview's bounds. I've been googling for hours, but nobody seems to have a good solution.
I'm able to get the right effect visually by sizing the UIScrollview to the size I want one page to be, turning off subview clipping, and placing it inside a container that passes all of its taps to the UIScrollview. The problem with this is that with Y pages visible, it lets you scroll the last page all the way to the left, leaving Y-1 empty pages after the last page. Anyone know a way around this, or another approach to the problem?
I think you need something like the previews in the safari mobile browser. Here is a website with some sample code.
Preview Sample Code
For the right end, try reducing the width of the scroll view's contentSize property enough that the scroll view will stop paging before it gets to the last page.
For the left end, reduce the frame.origin.x property of each page by the same amount. The first few pages will have a negative x position within the scroll view.
Essentially, makeing the scroll view think that it's content is only pages 2 through second to last.
For example:
// scrollView has been initialized and added to the view hierarchy according to the link in #richard's answer:
// http://blog.proculo.de/archives/180-Paging-enabled-UIScrollView-With-Previews.html
CGFloat pageNum=10;
CGFloat pageWidth=scrollView.frame.size.width;
CGFloat pageHeight=scrollView.frame.size.height;
CGFloat visibleWidth=320;
// Set scrollView contentSize and create pages:
CGFloat leftShift=floor(((visibleWidth-pageWidth)/2)/pageWidth)*pageWidth;
CGFloat contentSizeReduction=2*leftShift;
scrollView.contentSize = CGSizeMake(pageNum*pageWidth-contentSizeReduction,pageHeight);
for(int i=0; i<pageNum; i++) {
CGRect pageFrame = CGRectMake(i*pageWidth-leftShift, 0, pageWidth, pageHeight);
UIView *pageView = [[[UIView alloc] initWithFrame:pageFrame] autorelease];
// Initialize the page view for the current index here
[scrollView addSubview:pageView];
}
Forgive any typos in the code. I haven't tried this yet myself.
Let me know if it works.

What is the best way to display images/slides/containers on the iPad?

For an app that I am writing I need to display several views (in my case images, yet I guess that should not matter all that much) in a style similar to the way images are displayed in the Fotos app for the iPad. Consider this graphic:
Obviously on portrait view fewer slides can fit in per row than on Landscape view. What I have/want to do now:
Animate the addition of each slide by using a sliding animation
I already have a UIView subclass that represents a slide and that responds to touches the way I need it.
Where I am unsure is as to what is the best way of actually putting the slides onto the screen. I was originally just going to loop through them and place them onto the viewControllers view using the Frame of each slide (then I can do a count and increase the y-value after every 5 slides or so). Yet if I do it like that, I fear that my View will basically only support one screen orientation as I would need to relayout all the slides if the orientation changes, which seems rather a waste of resources to me (?).
How would you solve this problem? Is there maybe any "linebreak on overflow" ability such as with CSS (where a container automatically drops onto the next line if the float property is set and the parent container does not provide enough space)?
I am surely not the first person to think about this :)
Thanks for your answers!
There's no "linebreak on overflow" setting in Cocoa. If you want to make something that does that, you'll need to write code that lays out the slides. Here's a sample of the code I use to do it:
CGRect frame = CGRectMake(margins.left, margins.top, cellSize.width, cellSize.height);
for (UIButton *button in self.buttons) {
button.frame = frame;
// Move frame to next position
frame.origin.x += cellSize.width + cellSpacing;
if (frame.origin.x + frame.size.width > margins.left + contentWidth) {
frame.origin.x = leftMargin;
frame.origin.y += cellSize.height + cellSpacing;
}
}
I'm using UIButtons for each image, hence the self.buttons ivar.
Yes, you will need to relayout when the screen orientation changes. To do that, have a method like this:
- (void)layoutSubviews {
[super layoutSubviews];
[self layoutButtons];
}
Which calls your layout code. In my case, it's layoutButtons. This is in a subclass of UIScrollView, so when the view is autoresized after an autorotation, the layoutSubviews method gets called.
If you're using a UIScrollView, make sure you update the self.contentSize ivar too.

iPhone Horizontal Scrolling

I am trying to create an app with horizontal scrolling, so that one would be able to scroll horizontally through a series of images. I watched the WWDC Session 104 video on this, and while they made an interesting app, they flew through the basics of it very quickly.
I understand using the UIScrollView, and that I have to enable paging. After that they say that I should add more views as subviews of the scrollview, but I am not clear on how to do that. I am also not clear on how I add my images to those views.
As you can probably tell I am pretty new at this so any help would be appreciated.
You want to look into UIImageView. It's a view specifically for holding images.
When you add your images, you want to set their rects (probably using initWithFrame: for each UIImageView) so that:
the first image is at 0,0
the second image is at 320,0
third is at 640,0 (etc)
I.e. each image is 320 pixels right of the previous.
The final step is to set the contentSize for your UIScrollView -- this is a CGSize which describes the total size of the scroll view.
If you have 3 images, you would then set it to (320*3) * 480 using e.g.
myScrollView.contentSize = CGSizeMake(320*3, 480);
A lot of people, when they initialize the scroll view, have a for loop or similar which steps through the images they want to display. These for loops tend to look something like this:
CGFloat scrollWidth = 0.f;
for (UIImage *someImage in someNSArrayWithImages) {
UIImageView *theView = [[UIImageView alloc] initWithFrame:
CGRectMake(scrollWidth, 0, 320.f, 480.f)];
theView.image = someImage;
[myScrollView addSubview:theView];
[theView release];
scrollWidth += 320.f;
}
myScrollView.contentSize = CGSizeMake(scrollWidth, 480.f);
This way you'll get things lined up and you'll get the content size for you at the same time.
If you want to make it so that the scroll view "intelligently" scrolls to each image and stops when people slide left/right, you can do myScrollView.pagingEnabled = YES.
Hope that helps get you going.
Assuming you have "infinite" images, putting them all there at or before launch time in a huge UIScrollView will not be an option. (there is a limit to the size of a UIView)
The way I solved it: Make a UIScrollView covering the whole screen. It's content should be a UIView of 3*320 width and 480 height, extending 320px left and 320px right.
Put 3 UIImageView's in it, left, middle and right. Set paging=YES, so the uiscrollview clips to the 3 "pages" you've created.
Make sure your class is the delegate of the uiscrollview, and listen for
-(void)scrollViewDidEndDragging:(UIScrollView*)sv willDecelerate:(BOOL)notFinished
-(void)scrollViewDidEndDecelerating:(UIScrollView*)sv
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView*)sv
and make the appropriate transitions on hitting paging boundaries; shift images and set ContentOffset so you're looking at the center image again.
I suggest you make this first, and only then read on...
Then you will hit on a bug, documented here UIScrollView - (bounces = NO) seems to override (pagingEnabled = YES) and here http://www.iphonedevsdk.com/forum/iphone-sdk-development/935-paging-uiscrollview.html, which makes that you cannot disable bouncing and have paging enabled at the same time. So enable bouncing, and subclass UIScrollView, overruling setContentOffset in there to prevent bouncing. (having bouncing really enabled will make for a rather unusual user experience)
Have a look at Apple's PageControl sample code. It's fairly short and easy to follow so you'll get the gist of setting up a project where multiple view controllers are loaded as you swipe horizontally.
Once you have this setup then it's the view controller's responsibility to load its own content (in your case, an image). You should make sure you understand how to load images first (using threads, etc) before you tackle paging, etc.
Think of it as two independent tasks. The view control is responsible for loading and displaying an image. The scroll view with paging just tells the appropriate view controller when to load itself (it doesn't care what the view controller does once its loaded)
Good luck!