Introduction
Hello everyone, welcome to my third screeencast. This screencast is the result of a request made in the comments of my first post. I am going to be covering many topics in this post. But the general idea of the app we will build is that it will use an XML file online to get the URL and title of a given picture. For each URL and Title pair a view will be created with a UIImageView showing the image and a UILabel showing the title. Each of these views will be placed in a UIScrollView to flip through, like th functinoality of the Photos app.
Skill Level Medium
This app is going to require a decent amount of experience with Objective C and xCode. Also some minimal understanding of XML and XML schema/structure would be valuable.
Source Code
Available Here
Screencast
I film myself coding out the entire sample project for each post. I personally think going through the Screencast is the best way to learn. But feel free to look through the slides and text if that suites you better.
from on .
SCREENCAST ADDITION
Adding a final line to layoutSubviews should be:
[scrollview setFrame:workingFrame]; this will stop the scroll view from bouncing up and down.
Tutorial
iCodeBlogXMLImagesViewController.h:
@interface iCodeBlogXMLImagesViewController : UIViewController { IBOutlet UIScrollView *scrollview; } @property (nonatomic, retain) IBOutlet UIScrollView *scrollview;
iCodeBlogXMLImagesViewController.m
@synthesize scrollview;
iCodeBlogXMLView.h:
@interface iCodeBlogXMLView : UIView { IBOutlet UIImageView *imageView; IBOutlet UILabel *title; } @property (nonatomic, retain) IBOutlet UIImageView *imageView; @property (nonatomic, retain) IBOutlet UILabel *title; @end
iCodeBlogXMLView.m
@synthesize imageView; @synthesize title;
iCodeBlogXMLElement.h:
@interface iCodeBlogXMLElement : NSObject { UIImage *image; NSString *imageTitle; } @property (nonatomic, retain) UIImage *image; @property (nonatomic, retain) NSString *imageTitle; @end
iCodeBlogXMLElement.m
@synthesize image; @synthesize imageTitle;
iCodeBlogXMLImagesViewController.h:
#import <UIKit/UIKit.h> #import "iCodeBlogXMLElement.h" #import "iCodeBlogXMLView.h" @interface iCodeBlogXMLImagesViewController : UIViewController { IBOutlet UIScrollView *scrollview; NSXMLParser *parser; NSMutableString *currentAttribute; NSMutableArray *xmlElementObjects; iCodeBlogXMLElement *tempElement; } @property (nonatomic, retain) IBOutlet UIScrollView *scrollview; @property (nonatomic, retain) NSXMLParser *parser; @property (nonatomic, retain) NSMutableString *currentAttribute; @property (nonatomic, retain) NSMutableArray *xmlElementObjects; @property (nonatomic, retain) iCodeBlogXMLElement *tempElement; -(void)layoutSubview; @end
iCodeBlogXMLImagesViewController.m
@implementation iCodeBlogXMLImagesViewController @synthesize scrollview; @synthesize parser; @synthesize currentAttribute; @synthesize xmlElementObjects; @synthesize tempElement; ... - (void)viewDidLoad { [super viewDidLoad]; xmlElementObjects = [[NSMutableArray alloc] init]; parser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://losectrl-gaincommand.com/iCodeBlogHelper/Tutorial3/iCodeBlogImageXML.xml"]]; [parser setDelegate:self]; [parser parse]; } ... - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { }
iCodeBlogXMLImagesViewController.m
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if(![elementName compare:@"PictureInfo"]) { tempElement = [[iCodeBlogXMLElement alloc] init]; } else if(![elementName compare:@"imageURL"]) { currentAttribute = [NSMutableString string]; } else if(![elementName compare:@"imageTitle"]) { currentAttribute = [NSMutableString string]; } } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if(![elementName compare:@"PictureInfo"]) { [xmlElementObjects addObject:tempElement]; } else if(![elementName compare:@"imageURL"]) { NSURL *imageURL = [NSURL URLWithString:currentAttribute]; NSData *data = [NSData dataWithContentsOfURL:imageURL]; UIImage *image = [[UIImage alloc] initWithData:data]; [tempElement setImage:image]; } else if(![elementName compare:@"imageTitle"]) { NSLog(@"The image title is %@", currentAttribute); [tempElement setImageTitle:currentAttribute]; } else if(![elementName compare:@"Pictures"]) { [self layoutSubview]; } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { if(self.currentAttribute) { [self.currentAttribute appendString:string]; } }
iCodeBlogXMLImagesViewController.m
-(void)layoutSubview
{
CGRect workingFrame;
workingFrame.origin.x = 0;
workingFrame.origin.y = 0;
workingFrame.size.height = 480;
workingFrame.size.width = 320;
iCodeBlogXMLView *myView;
for(iCodeBlogXMLElement *element in [self xmlElementObjects])
{
myView = [[iCodeBlogXMLView alloc] initWithFrame:workingFrame];
NSLog(@"Element title is: %@", [element imageTitle]);
NSArray *topLeveObjects = [[NSBundle mainBundle] loadNibNamed:@"iCodeBlogXMLView" owner:nil options:nil];
for(id currentObject in topLeveObjects)
{
if([currentObject isKindOfClass:[iCodeBlogXMLView class]])
{
myView = (iCodeBlogXMLView *)currentObject;
}
}
[[myView imageView] setImage:[element image]];
[[myView title] setText:[element imageTitle]];
[myView setFrame:workingFrame];
[scrollview addSubview:myView];
workingFrame.origin.x = workingFrame.origin.x + 320;
}
workingFrame.size.width = workingFrame.origin.x;
[scrollview setContentSize:workingFrame.size];
workingFrame.origin.x = 0;
workingFrame.origin.y = 0;
workingFrame.size.width = 320;
workingFrame.size.height = 480;
}
iCodeBlogXMLImagesViewController.m
parser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://losectrl-gaincommand.com/iCodeBlogHelper/Tutorial3/iCodeBlogImageXMLB.xml"]];