Objective-c Novice - Needs help with animation - iphone

Im trying to add an animation of a monkey using a NSMutablAarray of UIImageViews. Im following a tutorial on youtube but when i compile i get a strange error: "stray '\357' in program." on the line "UIImage *img = [UIImage imageName: pictureName];"
Here are my h and m files..
#import "WinGameView.h"
#implementation WinGameView
#synthesize monkeyAnimation;
#synthesize monkeyImages;
-(IBAction)pushBack{
[self dismissModalViewControllerAnimated:YES];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
monkeyImages = [[NSMutableArray alloc] init];
for(int i = 1; i < 10; i++)
{
NSString *pictureName = [NSString stringWithFormat:#"monkey%d.gif",i];
UIImage *img = [UIImage imageName: pictureName];
if (img) [monkeyImages addObject:img];
}
[monkeyAnimation setAnimationImages:monkeyImages];
[monkeyAnimation setAnimationDuration:1.2f];
[monkeyAnimation startAnimating];
[super viewDidLoad];
}
and
#import <UIKit/UIKit.h>
#interface WinGameView : UIViewController {
IBOutlet UILabel *labelWin;
IBOutlet UILabel *labelWin2;
IBOutlet UIButton *buttonBack;
IBOutlet UIImageView *monkeyAnimation;
NSMutableArray *monkeyImages;
}
#property(nonatomic,retain)UIImageView *monkeyAnimation;
#property(nonatomic, retain)NSMutableArray *monkeyImages;
-(IBAction)pushBack;
#end
Does anyone know what i am doing wrong or why i am getting these wierd message. I have tried to look it up online but to no avail.

There is a stray "byte order mark" on that line (or even the line above or below). Retype the inside of the for loop by hand.

Related

How to load bundle of images in a scrollview with horrizondal scrolling in iphone?

I have an iPhone application in which i need to load a bulk of images (ie around 50),which has a small rect like (little above thumbnail) containing 3 in each row with 4 columns in one page, and i need to scroll horizontally to load the next 12 images and so on. Also i need to show the page number under it as 1,2 etc.
Can any body guide me in the right direction to achieve this in a scroll view ?i am really in a mess ,how to add imageview to a scrollview like this ,also each image view has its own buttons also.
The way i would tackle this problem goes as follows: (I am not going to provide many details as they are dependent on your particular needs and requirements).
.h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIScrollViewDelegate>
#property (unsafe_unretained, nonatomic) IBOutlet UIScrollView *scrollView;//assuming the scrollView is connected in a xib file
-(id)initWithImages:(NSArray*)images;//that could be whatever format you get your images(UIImage, urls to download, file names or custom views. Here we assume that the array contains instances of UIImage)
#end
.m file:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) NSArray *images;
#property (nonatomic, assign) CGFloat pageWidth;
#property (nonatomic, assign) int currentPage;
#end
#implementation ViewController
-(id)initWithImages:(NSArray*)images{
self = [super init];
if(self){
self.images = images;
}
return self;
}
-(void)viewDidLoad{
[super viewDidLoad];
[self.scrollView setDelegate:self];
[self.scrollView setContentSize:CGSizeMake(self.scrollView.frame.size.width*self.imageURLsArray.count,
self.scrollView.frame.size.height)];
[self.scrollView setPagingEnabled:YES];
[self.scrollView setShowsVerticalScrollIndicator:NO];
self.pageWidth = self.scrollView.frame.size.width;
for(int i = 0; i < self.images.count; i++){
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(self.scrollView.frame.size.width*i,
self.scrollView.frame.origin.y,
self.scrollView.frame.size.width,
self.scrollView.frame.size.height)];
imageView.image = [self.images objectAtIndex:i];
[self.scrollView addSubview:imageView];
}
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
int page = floor(scrollView.contentOffset.x - self.pageWidth/2)/self.pageWidth + 1;
if(self.currentPage != page){
NSLog(#"Scrolled to new page: %d", page);
self.currentPage = page;
//do additional things based on the fact that you have scrolled to a new page (like changing the page number)
}
}
#end
Use UItableview create custom cell with two imageviews on it and load that custom cell to cell for indexpath then create an nsarray and pass the image names into that array and then convert that image into data format for eg
nsdata *data = [NSdata dataWithcontents of url [array object at index:indexpath.row]];
cell.imageview.image = [uiimage imagewithdata:data];
for this you should know to create custom cells.

IBOutlet UIImageView

I got 30 of these codes, with the same implementation:
// .h
#interface ViewController : UIViewController{
IBOutlet UIImageView *circle;
IBOutlet UIImageView *circle2;
}
#property (nonatomic, retain) IBOutlet UIImageView *circle;
#property (nonatomic, retain) IBOutlet UIImageView *circle2;
// .m
#implementation ViewController
#synthesize circle;
#synthesize circle2;
- (void)viewDidLoad
{
circle = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"Circle.png"]];
circle2 = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"Circle.png"]];
}
And somewhere in my code, Im adding it as a subview.
My problem is,Is there a way to make it shorter, for it to be maintainable.
You can use one IBOutletCollection instead of 30 IBOutlets. You probably want to set the tag on each UIImageView though, so you can still tell them apart.
(This answer assumes you use a nib. Remove the lines where you instantiate the UIImageViews in viewDidLoad if so.)
If you use name like - Circle1.png, Circle2.png, then you can go for for loop for creating this in a loop.
Something like -
for (int i = 0; i < imageCount ; i++ ) {
circle = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:[NSString stringWithFormat: #"Circle%d.png" , i]]];
}
Is there a pattern to where you are putting these views in their superview? If so, you could use a for loop that goes to 30 and programmatically create the views and add them to their superview.
So for example:
for (i = 0; i < 100; i++)
{
UIImageView* circle = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"Circle.png"]];
[self.view addSubview:circle];
}
Would add 100 of the image views you would want. Of course you will need to adjust the positions of each of these views in the loop, but this is the general idea.
while creating this viewcontroller pass the frame as a parameter.thats the only thing changing rite??.the image is same and as there are no other properties .. it may work

UIImageView Delay or revert to different frame

Ok so I have been searching and have been unable to find an answers to this problem. (And I assume I can't find it because it is a very easy answer that everyone seems to know but me.) I am creating an app for IOS, where there is some opening animation and then I need the opening animation to stop and then different animation to take place instead. So I have the opening animation working fine and I have it stopping on the last frame. How do I get the new animation to start at the end of the opening animation? I am using UIImageView under the viewDidLoad() function. Here is my code for the ViewController.m file:
#implementation ViewController
#synthesize hook_drop_one;
#synthesize hook_swing_one;
- (void)viewDidLoad
{
[super viewDidLoad];
hook_drop_aone=[[NSMutableArray alloc] init];
for (int i=1; i<16; i++) {
NSString *hookpic=[NSString stringWithFormat: #"hook%d.png",i];
UIImage *img = [UIImage imageNamed:hookpic];
if (img) [hook_drop_aone addObject:img];
[hook_drop_one setAnimationImages:(hook_drop_aone)];
[hook_drop_one setAnimationDuration:0.9f];
[hook_drop_one setAnimationRepeatCount:1];
[hook_drop_one startAnimating];
}
hook_swing_aone=[[NSMutableArray alloc] init];
for (int i=1; i<230; i++) {
NSString *hookswingpic=[NSString stringWithFormat: #"hookswing%d.png",i];
UIImage *img = [UIImage imageNamed:hookswingpic];
if (img) [hook_swing_aone addObject:img];
[hook_swing_one setAnimationImages:(hook_swing_aone)];
[hook_swing_one setAnimationDuration:10.2f];
[hook_swing_one startAnimating];
}
}
My code fro the ViewController.h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController{
IBOutlet UIImageView *hook_drop_one;
NSMutableArray *hook_drop_aone;
IBOutlet UIImageView *hook_swing_one;
NSMutableArray *hook_swing_aone;
}
#property (nonatomic,retain)UIImageView *hook_drop_one;
#property (nonatomic,retain)NSMutableArray *hook_drop_aone;
#property (nonatomic,retain)UIImageView *hook_swing_one;
#property (nonatomic,retain)NSMutableArray *hook_swing_aone;
#end
Now I understand why both animations are running at the same time when the app loads. I need to figure out how to trigger one animation after the first one stops, or set a delay for the second animation.
Anyone got any ideas?
You can using
[CATransaction setCompletionBlock:^{ ... }]
please review session 421 WWDC 2011 - there is all info in second part of session.
Use i for determining the timming for your next animation , or you can start animation by touch event.

making header file than can be used anywhere for iphone

i want to make headerfile Rimage.h and m that i can use anywhere but i have a problem here
this is my
Rimage.h
#class Rahul_imageplaceCordinatesViewController;
#interface Rimage : NSObject {
Rahul_imageplaceCordinatesViewController *vc;
}
-(void)addImageSubViewAtX:(CGFloat)x atY:(CGFloat)y;
#property (nonatomic,copy) Rahul_imageplaceCordinatesViewController *vc;
+(void)check1;
#end
and this is my .m
#implementation Rimage
#synthesize vc;
/// this method let you have image with given X n Y
- (void)addImageSubViewAtX:(CGFloat)x atY:(CGFloat)y {
CGRect myImageRect1 = CGRectMake(x, y, 30.0f, 30.0f);
UIImageView *myImage1 = [[UIImageView alloc] initWithFrame:myImageRect1];
[myImage1 setImage:[UIImage imageNamed:#"status_finish.gif"]];
myImage1.tag = 1000;
myImage1.userInteractionEnabled = YES;
[self.view addSubview:myImage1];
}
now in my mainVC
i am calling like this
- (void)viewDidLoad {
Rimage *hw = [[Rimage alloc] init];
//[hw check1];
[Rimage check1];
[hw addImageSubViewAtX:160.0 atY:190.0];
}
but i cant display that image i dont know why :(
First I noticed is your #property you are making a "copy" of the ViewController in vc, I suspect that's a bad idea, you just want to assign or retain it.
Second, in addImageSubViewAtX, you have:
[self.view addSubview:myImage1];
But what is self there? It is the instance of Rimage. I'm guessing that perhaps you meant to add the image to the view in vc?? I don't see that vc is ever used in the code you provided so what is it for?
[vc.view addSubview:myImage1];

UIButton that cycles through images when clicked

I have three images that I want to cycle through when clicking on a UIButton.
How would I go about doing this?
This is what I have so far, but it's not really working.
//the images
NSString* imageNames[] = {"MyFirstImage", "AnotherImage", whatever else};
int currentImageIndex = 0;
and
- (IBAction)change{
UIImage* imageToShow = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource: imageNames[currentImageIndex] ofType:#"png"];
if( currentImageIndex++ == sizeof(imageNames)/sizeof(NSString)) //check to see if you hit the last image
{
currentImageIndex = 0; //start over
}
}
Ideas?
Any help will be greatly appreciated! Thanks!
Steven's suggestion to subclass UIButton is a good one. Once you get a some more experience with Objective C, you should consider his approach, but I can tell by the code you've posted that you're new to Objective C, so you may need to learn to use the basic Foundation classes first.
One reason your code isn't working is because you're trying to pass C string literals to pathForResource:, which requires an NSString object. NSStrings are objects in Objective C, not character pointers as they are in C. You can construct an NSString object using the literal syntax, #"quotes-with-an-at-in-front".
Here is code that implements the algorithm you attempted to write, using Objective C Foundation classes rather than C data types:
// YourController.h
#interface YourController : UIViewController {
NSArray *imageNames;
NSInteger currentImageIndex;
UIButton *yourButton;
}
#property (nonatomic, retain) NSArray *imageNames;
#property (nonatomic, retain) IBOutlet UIButton *yourButton; // Presumably connected in IB
- (IBAction)change;
#end
// YourController.m
#import "YourController.h"
#implementation YourController
#synthesize imageNames, yourButton;
- (void)dealloc {
self.imageNames = nil;
self.yourButton = nil;
[super dealloc];
}
- (void)viewDidLoad {
self.imageNames = [NSArray arrayWithObjects:#"MyFirstImage", #"AnotherImage", nil];
currentImageIndex = 0;
[super viewDidLoad];
}
- (IBAction)change {
UIImage* imageToShow = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[imageNames objectAtIndex:currentImageIndex] ofType:#"png"];
currentImageIndex++;
if (currentImageIndex >= imageNames.count) {
currentImageIndex = 0;
}
[yourButton setImage:imageToShow forState:UIControlStateNormal];
}
#end
You will want to subclass UIButton and add a new property that maintains state. You will also want to have three properties to maintain the images of the three new states. Then in your "drawRect:" method, swap out the standard buttons images based on your state and then call the [super drawRect:] method.