Scroll to xib (pagecontrol) - objective-c

i had a small question, i'm using this code to scroll from color to color:
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];
you can scroll from color to color, but is there a way to scroll to another xib file?
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = self.scrollView.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollView.frame.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [colors objectAtIndex:i];
[self.scrollView addSubview:subview];
[subview release];
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * colors.count, self.scrollView.frame.size.height);
}

This tutorial will help you out: http://www.iosdevnotes.com/2011/03/uiscrollview-paging/
(i think that you've use this tutorial)
but on the last line of the tutorial:
Update: In the comments, some people have asked about placing buttons
inside the scroll view, and also about setting up the scroll view
using Interface Builder. I’ve added some code that includes buttons
here, and a version using Interface Builder here.
So here is the link to move to xib files: https://github.com/cwalcott/UIScrollView-Paging/tree/buttons-ib
Good luck,
Nathan

Instead of preparing UIView's and adding them to a scrollview, you could indeed use [[NSBundle mainBundle] loadNibNamed... to load several nib (which are compiled xib) and add them to a scrollview, and then scroll them up and down, or back and forth.

Related

Render Title of MKPolygon

I'm trying to render MKPolygon using the following code:
NSMutableArray *overlays = [NSMutableArray array];
for (NSDictionary *state in states) {
NSArray *points = [state valueForKeyPath:#"point"];
NSInteger numberOfCoordinates = [points count];
CLLocationCoordinate2D *polygonPoints = malloc(numberOfCoordinates * sizeof(CLLocationCoordinate2D));
NSInteger index = 0;
for (NSDictionary *pointDict in points) {
polygonPoints[index] = CLLocationCoordinate2DMake([[pointDict valueForKeyPath:#"latitude"] floatValue], [[pointDict valueForKeyPath:#"longitude"] floatValue]);
index++;
}
MKPolygon *overlayPolygon = [MKPolygon polygonWithCoordinates:polygonPoints count:numberOfCoordinates];
overlayPolygon.title = [state valueForKey:#"name"];
[overlays addObject:overlayPolygon];
free(polygonPoints);
}
[self.stateMapView addOverlays:overlays];
I used the following code to provide stroke and fill colors:
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay NS_AVAILABLE(10_9, 7_0);
{
if ([overlay isKindOfClass:[MKPolygon class]])
{
MKPolygonRenderer *pv = [[MKPolygonRenderer alloc] initWithPolygon:overlay];
pv.fillColor = [UIColor redColor];
pv.strokeColor = [UIColor blackColor];
return pv;
}
return nil;
}
Do I need to do something to render the Title? I think I should enable a configuration or something but I'm new to MapView. Or I need to create a UILabel?
Overlays don't automatically show their titles like annotations can (in their callout actually) so there's nothing you "need to do" or any configuration that you can enable.
A simple workaround to show titles on overlays is, as you suggest, to create a UILabel.
However, this UILabel should be added to an annotation view that is positioned at each overlay's center.
A minor drawback (or maybe not) to this method is that the titles will not scale with the zoom of the map -- they'll stay the same size and can eventually collide and overlay with other titles (but you may be ok with this).
To implement this approach:
For each overlay, add an annotation (using addAnnotation: or addAnnotations:) and set the coordinate to the approximate center of the overlay and the title to the overlay's title.
Note that since MKPolygon implements both the MKOverlay and the MKAnnotation protocols, you don't necessarily need to create a separate annotation class or separate objects for each overlay. MKPolygon automatically sets its coordinate property to the approximate center of the polygon so you don't need to calculate anything. You can just add the overlay objects themselves as the annotations. That's how the example below does it.
Implement the mapView:viewForAnnotation: delegate method and create an MKAnnotationView with a UILabel in it that displays the title.
Example:
[self.stateMapView addOverlays:overlays];
//After adding the overlays as "overlays",
//also add them as "annotations"...
[self.stateMapView addAnnotations:overlays];
//Implement the viewForAnnotation delegate method...
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
//show default blue dot for user location...
return nil;
}
static NSString *reuseId = #"ann";
MKAnnotationView *av = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (av == nil)
{
av = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
av.canShowCallout = NO;
//add a UILabel in the view itself to show the title...
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 30)];
titleLabel.tag = 42;
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.textColor = [UIColor blackColor];
titleLabel.font = [UIFont boldSystemFontOfSize:16];
titleLabel.textAlignment = NSTextAlignmentCenter;
titleLabel.minimumScaleFactor = 0.5;
[av addSubview:titleLabel];
av.frame = titleLabel.frame;
}
else
{
av.annotation = annotation;
}
//find the UILabel and set the title HERE
//so that it gets set whether we're re-using a view or not...
UILabel *titleLabel = (UILabel *)[av viewWithTag:42];
titleLabel.text = annotation.title;
return av;
}
The alternative approach is to create a custom overlay renderer and do all the drawing yourself (the polygon line, the stroke color, the fill color, and the text). See Draw text in circle overlay and Is there a way to add text using Paths Drawing for some ideas on how to implement that.

Advance a UIScrollView with button

Hi I have a UiScroll view that contains an array of images and I can swipe back and forth to advance the loaded images. However, I also would like to be able to control the scroll view advancing with a button action. Here is the code for the scroll view:
int PageCount = 28;
NSMutableArray *arrImageName =[[NSMutableArray alloc]initWithObjects:#"S2-4.png",#"D3-4.png",#"F2-4.png",#"B6-4.png",#"D6-4.png",#"S1-4.png",#"B7-4.png", #"D2-4.png",#"F7-4.png",#"B1-4.png",#"F3-4.png",#"D5-4.png",#"S3-4.png",#"B2-4.png",#"F5-4.png",#"D4-4.png",#"S7-4.png",#"F1-4.png",#"B3-4.png",#"S4-4.png",#"F6-4.png",#"D1-4.png",#"B4-4.png",#"S5-4.png",#"F4-4.png",#"D7-4.png",#"S6-4.png",#"B5-4.png",nil];
scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
scroller.scrollEnabled=YES;
scroller.backgroundColor = [UIColor clearColor];
[scroller setShowsHorizontalScrollIndicator:NO];
scroller.pagingEnabled = YES;
scroller.bounces = NO;
[self.view addSubview:scroller];
width=scroller.frame.size.width;
xPos=0;
for (int i=0; i<PageCount; i++)
{
UIImageView *ImgView = [[UIImageView alloc]initWithFrame:CGRectMake(xPos, 0, scroller.frame.size.width, scroller.frame.size.height)];
[ImgView setImage:[UIImage imageNamed:[arrImageName objectAtIndex:i]]];
[scroller addSubview:ImgView];
scroller.contentSize = CGSizeMake(width, 0);
width +=scroller.frame.size.width;
xPos +=scroller.frame.size.width;
}
And then I have my button action but how would I perform the same advancing with the button? Thank you.
- (void)nextPhoto: (id)sender {
}
I am relatively new to xcode and not sure how to manipulate the scroll view in this action.
Have a look at scrollRectToVisible:animated: - that will scroll things nicely to a specific place.

UIScrollView and Autoration issues

I'm trying to understand an issue I'm having with an iOS Universal app. I have a UIScrollView which I want the page of to take up the full dimension of the device and adjust itself when rotating.
In my viewDidLoad method, I'm testing with:
NSArray *colors = [NSArray arrayWithObjects:[UIColor orangeColor], [UIColor cyanColor], [UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];
for (int i = 0; i < colors.count; i++) {
CGRect frame;
frame.origin.x = _scrollView.bounds.size.width * i;
frame.origin.y = 0;
frame.size = _scrollView.bounds.size;
UIView *subview = [[UIView alloc] initWithFrame:frame];
subview.backgroundColor = [colors objectAtIndex:i];
[_scrollView addSubview:subview];
}
_scrollView.contentSize = CGSizeMake(_scrollView.bounds.size.width * colors.count, _scrollView.bounds.size.height);
then I added in the didRotateFromInterfaceOrientation method:
_scrollView.contentSize = CGSizeMake(_scrollView.bounds.size.width * colors.count, _scrollView.bounds.size.height);
for (int i= 0; i< colors.count; i++)
{
CGRect frame;
frame.origin.x = _scrollView.bounds.size.width * i;
frame.origin.y = 0;
frame.size = _scrollView.bounds.size;
UIView *subview= [[_scrollView subviews] objectAtIndex:i];
subview.frame= frame;
}
This seems to work, but I seem to have some clipping on the main view while the device is rotating.
Here's a screenshot of what happens when rotating:
I thought this happened because I changed the size after it was rotated, but I tried to handle it in the willRotateToInterfaceOrientation method, but it gave the wrong result...
Am I handling this incorrectly?
What would be the correct approach?
TIA!
S.
Am I handling this incorrectly?
You should put the code that changes the bounds in willRotateToInterfaceOrientation, but do so in an animation block (using [UIView animateWithDuration:0.4 animations:...])_so that the transition will be smooth rather than immediate.
An extra note is that inside willRotateToInterfaceOrientation, the parent view will not yet have been resized, so you cannot depend on it's bounds to calculate the final position of the views, rather you must do so manually.

Trying to display images using UIScrollView

I want to create an simple app that will contain one centered image at the first start screen, than upon swipe gesture(right, left) change images.
I'm very new to this so here is what I though is what I'm looking for http://idevzilla.com/2010/09/16/uiscrollview-a-really-simple-tutorial/ .
This is the code I have in my controller implementation :
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
[myDictionary setObject:#"img1.jpg" forKey:#"http://www.testweb.com"];
[myDictionary setObject:#"img2.jpg" forKey:#"http://www.test2.com"];
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scroll.pagingEnabled = YES;
NSInteger numberOfViews = [myDictionary count];
for (NSString* key in myDictionary) {
UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:[myDictionary objectForKey:key]]];
CGRect rect = CGRectMake(10.0f, 90.0f, image.size.width, image.size.height);
UIImageView * imageView = [[UIImageView alloc] initWithFrame:rect];
[imageView setImage:image];
CGPoint superCenter = CGPointMake([self.view bounds].size.width / 2.0, [self.view bounds].size.height / 2.0);
[imageView setCenter:superCenter];
self.view.backgroundColor = [UIColor whiteColor];
[scroll addSubview:imageView];
}
scroll.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
[self.view addSubview:scroll];
}
My first issue here is that I get img2 on my initial screen instead of img1. And second issue is when I swipe right I get white screen and no image on it. Any suggestions what I missed, what I can try/read etc?
EDIT :
I'm looking to do this the "lightest" possible way, using no fancy galleries api etc. Just display couple of really small images(i.e 200x200 px) centered on the screen that I can swipe back and forth(should't be too hard). Well everything is hard when learning a new language.
There is a project on github MWPhotoBrowser that allows you to put in a set of images which are viewed one at a time. You can then scroll from one image to the next with a swipe gesture. It is also easy to add functionality and it should give you a good understanding of how this is done. There is also Apple's PhotoScroller example which gives you straight forward code in how to do this same thing and also tile your images. Since you are new to iOS you may want to first look at both of these examples or possibly just use them as your photo viewer.
Your problem is likely to be the fact that you are setting CGRect rect = CGRectMake(10.0f, 90.0f, image.size.width, image.size.height); for both of your image views. This means that both of your UIImageView objects are placed in exactly the same position (both are positioned at 10.f on the x-coordinate of the scrollview). As the second image view is added last it covers the first and means that there is white space to the right of it.
In order to fix this you could try something like...
- (void)viewDidLoad
{
//your setup code
float xPosition = 10.f;
for (NSString* key in myDictionary) {
UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:[myDictionary objectForKey:key]]];
CGRect rect = CGRectMake(xPosition, 90.0f, image.size.width, image.size.height);
xPosition += image.size.width;
//rest of your code...
}
//rest of your code
}
The above would mean that the second view is positioned on the x-coordinate at 10 + the width of the first image. Note that I haven't tested my answer.
First off the images are placed on top of each other.
CGPoint superCenter = CGPointMake([self.view bounds].size.width / 2.0, [self.view bounds].size.height / 2.0);
[imageView setCenter:superCenter];
Right here you are setting both images to be placed at the center of the screen. The second thing is your using an NSDictionary and looping through the keys. NSDictionary are not orders like an array is. You would have to sort the keys to us it in a specific order. So Barjavel had it right but skipped over the fact your setting the images to center. Try this:
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *myArray = [[NSArray alloc] initWithObjects:#"img1.jpg", #:image2.jpg", nil];
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scroll.pagingEnabled = YES;
NSInteger numberOfViews = [myArray count];
int xPosition = 0;
for (NSString* image in myArray) {
UIImage * image = [UIImage imageNamed:image];
CGRect rect = CGRectMake(xPosition, 90.0f, image.size.width, image.size.height);
UIImageView * imageView = [[UIImageView alloc] initWithFrame:rect];
[imageView setImage:image];
self.view.backgroundColor = [UIColor whiteColor];
[scroll addSubview:imageView];
xPosition += image.size.width;
}
scroll.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
[self.view addSubview:scroll];
}

UIScrollView Help

Is there a way to put several UIViews In a UIScrollView in a tabbar page. If so, how would I do that? To make it simple, Imageine the homescreen icons on the springboard. Each page is a UIView. I want to basically put this on a tabbar page. Is this possible? How would I do it?
NOTE:
First try to accept the answers then only you will get lot of good answer from our seniors.....
first create the uiscrollview and then add that it to the tabbar... for creating the uiscrollview
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
scroll.pagingEnabled = YES;
NSInteger numberOfViews = 3;
for (int i = 0; i < numberOfViews; i++) {
CGFloat yOrigin = i * self.view.frame.size.width;
UIView *awesomeView = [[UIView alloc] initWithFrame:CGRectMake(yOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];
awesomeView.backgroundColor = [UIColor colorWithRed:0.5/i green:0.5 blue:0.5 alpha:1];
[scroll addSubview:awesomeView];
[awesomeView release];
}
scroll.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
[self.view addSubview:scroll];