Managing multiple NSArrays on a different UIViewController? - ios

is it possible to manage multiple NSArrays on a different View Controller?
Here's my example:
I am currently working with two View Controllers:
TableViewController serves as a main menu. I've set up multiple UIButtons, each has a tag and when the user presses a button, it'll take them to the TableOneViewController.
In TableOneViewController, so far I've set up an UIImageView and a UIButton, every time the user presses the button, the UIImageView changes the image through an NSArray.
I want to use the tags on the TableViewController to manage the NSArrays of the TableOneViewController. Is this possible? So far, my code is not working.
Here's the code. Thanks!
TableViewController.m
- (IBAction)tableSelection:(id)sender
{
TableOneViewController *TOVC = [self.storyboard instantiateViewControllerWithIdentifier:#"TableOneViewController"];
if ([sender tag] == 1) {
[[NSUserDefaults standardUserDefaults] setObject:TOVC.numOne forKey:#"num"];
[[NSUserDefaults standardUserDefaults] setObject:#"1.png" forKey:#"num2"];
}
if ([sender tag] == 2) {
[[NSUserDefaults standardUserDefaults] setObject:TOVC.numTwo forKey:#"num"];
[[NSUserDefaults standardUserDefaults] setObject:#"2.png" forKey:#"num2"];
}
if ([sender tag] == 3) {
[[NSUserDefaults standardUserDefaults] setObject:TOVC.numThree forKey:#"num"];
[[NSUserDefaults standardUserDefaults] setObject:#"3.png" forKey:#"num2"];
}
[self presentViewController:TOVC animated:YES completion:nil];
}
TableOneViewController.m
- (IBAction)nextButton:(id)sender
{
int index = tableCounter++ % [self.numOne count];
self.num.image = self.numOne[index];
}
- (void)viewDidLoad
{
self.num.image = [UIImage imageNamed:[[NSUserDefaults standardUserDefaults] objectForKey:#"num"]];
self.num2.image = [UIImage imageNamed:[[NSUserDefaults standardUserDefaults] objectForKey:#"num2"]];
[super viewDidLoad];
tableCounter = 10;
self.numOne = [NSArray arrayWithObjects:
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"4.png"],
[UIImage imageNamed:#"5.png"],
[UIImage imageNamed:#"6.png"],
[UIImage imageNamed:#"7.png"],
[UIImage imageNamed:#"8.png"],
[UIImage imageNamed:#"9.png"],
[UIImage imageNamed:#"10.png"],
[UIImage imageNamed:#"1.png"],
nil];
self.numTwo = [NSArray arrayWithObjects:
[UIImage imageNamed:#"20.png"],
[UIImage imageNamed:#"30.png"],
[UIImage imageNamed:#"40.png"],
[UIImage imageNamed:#"50.png"],
[UIImage imageNamed:#"60.png"],
[UIImage imageNamed:#"70.png"],
[UIImage imageNamed:#"80.png"],
[UIImage imageNamed:#"90.png"],
[UIImage imageNamed:#"100.png"],
[UIImage imageNamed:#"10.png"],
nil];
self.numThree = [NSArray arrayWithObjects:
[UIImage imageNamed:#"200.png"],
[UIImage imageNamed:#"300.png"],
[UIImage imageNamed:#"400.png"],
[UIImage imageNamed:#"500.png"],
[UIImage imageNamed:#"600.png"],
[UIImage imageNamed:#"700.png"],
[UIImage imageNamed:#"800.png"],
[UIImage imageNamed:#"900.png"],
[UIImage imageNamed:#"1000.png"],
[UIImage imageNamed:#"100.png"],
nil];
}

The problem is that you pass the array before presenting the view controller (viewDidLoad hasn't be called yet), then you present it, but you initialize numOne (and the other arrays) in viewDidLoad. I suggest to use lazy initialization, here's the example for numOne, write the same for the other two arrays:
- (NSArray*) numOne
{
if(!_numOne)
{
_numOne= [NSArray arrayWithObjects:
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"4.png"],
[UIImage imageNamed:#"5.png"],
[UIImage imageNamed:#"6.png"],
[UIImage imageNamed:#"7.png"],
[UIImage imageNamed:#"8.png"],
[UIImage imageNamed:#"9.png"],
[UIImage imageNamed:#"10.png"],
[UIImage imageNamed:#"1.png"],
nil];
}
return _numOne;
}
However this is not the purpose of NSUserDefaults, I consider this approach bad design. It's better if you keep an ivar in TableOneViewController that points to one of the three arrays (same for the image name).
Edit
This is how I would implement the mechanism: an additional property that points to one of the three arrays in TableOneViewController:
#property (nonatomic, weak) NSArray* currentArray;
This pointer should point to the correct array, according to the tag of the sender that triggered tableSelection: :
// TableViewController
- (IBAction)tableSelection:(id)sender
{
TableOneViewController *TOVC = [self.storyboard instantiateViewControllerWithIdentifier:#"TableOneViewController"];
switch([sender tag]) {
case 1:
TOVC.currentArray= TOVC.numOne;
break;
case 2:
TOVC.currentArray= TOVC.numTwo;
break;
case 3:
TOVC.currentArray= TOVC.numThree;
break;
default:
return;
}
[self presentViewController:TOVC animated:YES completion:nil];
}
// TableOneViewController
- (IBAction)nextButton:(id)sender
{
int index = tableCounter++ % [self.currentArray count];
self.num.image = self.currentArray[index];
}

It doesn't work because
TableOneViewController *TOVC = [self.storyboard instantiateViewControllerWithIdentifier:#"TableOneViewController"];
creates a completely new instance of your TableOneViewController. I would use a singleton retaining the arrays and any other info I need as a single access point during the execution of my program.

Related

Error when load images like gif in uiimageview

I want to load images like gif. It work perfectly when i go to viewcontroller by push segue but when i go to viewcontroller by modal segue not load images in imageview.
_ivDummy.animationImages = [NSMutableArray arrayWithObjects:
[UIImage imageNamed:#"1.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"4.png"],
[UIImage imageNamed:#"5.png"],
[UIImage imageNamed:#"6.png"],
[UIImage imageNamed:#"7.png"],
[UIImage imageNamed:#"8.png"],
nil];
[_ivDummy setBackgroundColor:[UIColor redColor]];
_ivDummy.animationDuration = 1.0f;
_ivDummy.animationRepeatCount = INFINITY;
[_ivDummy startAnimating];
Please, Help me.
In Progress Hud
[indicator removeFromSuperview];
UIImageView* animatedImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 45.0f, 45.0f)];
animatedImageView.animationImages = [NSMutableArray arrayWithObjects:
[UIImage imageNamed:#"1.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"4.png"],
[UIImage imageNamed:#"5.png"],
[UIImage imageNamed:#"6.png"],
[UIImage imageNamed:#"7.png"],
[UIImage imageNamed:#"8.png"],
nil];
//[animatedImageView setBackgroundColor:[UIColor redColor]];
animatedImageView.animationDuration = 1.0f;
animatedImageView.animationRepeatCount = INFINITY;
[animatedImageView startAnimating];
indicator=animatedImageView;
[self addSubview:indicator];
Instead of using
- (void)viewDidLoad method try using
- (void)viewWillAppear:(BOOL)animated
-(void)viewWillAppear:(BOOL)animated
{
_ivDummy.animationImages = [NSMutableArray arrayWithObjects:
[UIImage imageNamed:#"1.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
[UIImage imageNamed:#"4.png"],
[UIImage imageNamed:#"5.png"],
[UIImage imageNamed:#"6.png"],
[UIImage imageNamed:#"7.png"],
[UIImage imageNamed:#"8.png"],
nil];
[_ivDummy setBackgroundColor:[UIColor redColor]];
_ivDummy.animationDuration = 1.0f;
_ivDummy.animationRepeatCount = INFINITY;
[_ivDummy startAnimating];
}
You can override this method to perform custom tasks associated with displaying the view.

NSArray [UIImage setContentMode:]

I want to put defaults images if i don't have images from url feed.
if(![[stories objectAtIndex:storyIndex] valueForKey:#"url"]==nil)
{ NSNumber *numberOfKeyInstances = [stories valueForKey:#"key"];
imageArray=[NSArray arrayWithObjects:[UIImage imageNamed:#"1.png"],nil];
int randomNumber_ = rand ()%19;
UIImage *image = [imageArray objectAtIndex:indexPath.row];
cell.imag=image;
}
else{
if (![[[stories objectAtIndex:storyIndex] valueForKey:#"url"] isEqualToString:#""]) {
[cell.imag setImageWithURL:[NSURL URLWithString:[[stories objectAtIndex:storyIndex] objectForKey:#"url"]] placeholderImage:[UIImage imageNamed:#"Alb.png"]];
}
}
This is my code, but i get [UIImage setContentMode:]: unrecognized selector sent to instance 0x7f908c1dcce0'
How can i solved?
Firstly, imageArray is initialised with only one image. So calling [imageArray objectAtIndex:indexPath.row] is a problem. You dont need an image array for that. Secondly, the argument inside the first if statement doesn't look right.
Also, as #midhun-mp Pointed out, u should be probably using cell.imag.image.
Try this :
if([[stories objectAtIndex:storyIndex] valueForKey:#"url"] == nil)
{
cell.imag.image = [UIImage imageNamed:#"1.png"];
}
else if ([[[stories objectAtIndex:storyIndex] valueForKey:#"url"] isEqualToString:#""])
{
cell.imag.image = [UIImage imageNamed:#"1.png"];
}
else
{
//SET YOUR IMAGE HERE
}
Try to change
UIImage *image = [imageArray objectAtIndex:indexPath.row];
to
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:[imageArray objectAtIndex:indexPath.row]]];
I suspect that cell.imag is a UIImageView not UIImage property.
So you need to change:
cell.imag=image;
to
cell.imag.image = image;

Issue using displaying Image with NSMutableArray

I am very new to xcode and I am playing around with image arrays and NSMutableArray. When I run the code below it just print out the names of the image for example "image1.png". Any tips to fix this problem would be appreciated. Thanks.
- (NSMutableArray*)restaurantArray;
{
if (_restaurantArray == nil) {
_restaurantArray = [[NSMutableArray alloc] initWithObjects:
#"image1.png",
#"image2.png",
#"image3.png",
nil];
}
return _restaurantArray;
}
-(NSString*) randomRestaurant
{
int random = arc4random_uniform(self.restaurantArray.count);
return [self.restaurantArray objectAtIndex:random];
}
You could do it in this way also.
- (NSMutableArray*)restaurantArray;
{
if (_restaurantArray == nil) {
_restaurantArray = [[NSMutableArray alloc] initWithObjects:[UIImage imageNamed:#"image1.png"],
[UIImage imageNamed:#"image2.png"],
[UIImage imageNamed:#"image3.png"],
nil];
}
return _restaurantArray;
}
Do you mean this?:
NSString *imageName = [self randomRestaurant];
UIImage *image = [UIImage imageName:imageName];
If you want to display the image then do this:
Suppose you have an imageview name imgView,
imgView.image = [UIImage imageNamed:[self randomRestaurant]];
Or, if you just want the image, then call this:
UIImage *img = [UIImage imageNamed:[self randomRestaurant]];
In you given code, you are just returning the name of the image, not the actual image. If you want an array of image then you can do it by this way:
-(NSMutableArray*) restaurantArray;
{
if (_restaurantArray == nil) {
UIImage *img = [UIImage imageNamed:#"image1.png"];
UIImage *img1 = [UIImage imageNamed:#"image2.png"];
UIImage *img2 = [UIImage imageNamed:#"image3.png"];
_restaurantArray = [[NSMutableArray alloc] initWithObjects:
img,
img1,
img2,
nil];
}
return _restaurantArray;
}
-(UIImage*) randomRestaurant
{
int random = arc4random_uniform(self.restaurantArray.count);
return [self.restaurantArray objectAtIndex:random];
}
Hope this helps.. :)

Change the speed of an animation halfway through?

I want my app to play an animation when a press a button however I want the speed of the animation to slow down halfway through? Currently my app plays a sound/animation when I press a button, however the last 50% of the frames are too fast and I want it to slow down.
Here is my code:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController {
}
- (IBAction)Button {
AudioServicesPlaySystemSound(SoundID);
}
-(IBAction)startanimating{
animatedimage.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"frames_00.png"],
[UIImage imageNamed:#"frames_05.png"],
[UIImage imageNamed:#"frames_10.png"],
[UIImage imageNamed:#"frames_15.png"],
[UIImage imageNamed:#"frames_20.png"],
[UIImage imageNamed:#"frames_25.png"],
[UIImage imageNamed:#"frames_30.png"],
[UIImage imageNamed:#"frames_35.png"],
[UIImage imageNamed:#"frames_40.png"],
[UIImage imageNamed:#"frames_45.png"],
[UIImage imageNamed:#"frames_50.png"],
[UIImage imageNamed:#"frames_50.png"],
[UIImage imageNamed:#"frames_45.png"],
[UIImage imageNamed:#"frames_40.png"],
[UIImage imageNamed:#"frames_35.png"],
[UIImage imageNamed:#"frames_30.png"],
[UIImage imageNamed:#"frames_25.png"],
[UIImage imageNamed:#"frames_20.png"],
[UIImage imageNamed:#"frames_15.png"],
[UIImage imageNamed:#"frames_10.png"],
[UIImage imageNamed:#"frames_05.png"],
[UIImage imageNamed:#"frames_00.png"],nil];
[animatedimage setAnimationRepeatCount:1];
animatedimage.animationDuration = 0.7;
[animatedimage startAnimating];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL *buttonURL = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"AVTREV" ofType:#"mp3"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)buttonURL, &SoundID);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Frame 50 is where I want it to play at a much slower speed. Any help would be fantastic thank you!
With the current code you have an array with 22 items in it. To achieve the desired effect, you can use an array with 33 items in it, by duplicating each item after frame_50, so that the entries in the array look like this
00 05 10 ... 45 50 50 50 45 45 40 40 ... 05 05 00 00
Since the filenames follow a predictable pattern, you can even use a loop to create the array.
int i;
NSString *name;
NSMutableArray *tempArray = [NSMutableArray new];
for ( i = 0; i <= 50; i += 5 )
{
name = [NSString stringWithFormat:#"frames_%02d.png", i];
[tempArray addObject:[UIImage imageNamed:name]];
}
for ( i = 50; i >= 0; i -= 5 )
{
name = [NSString stringWithFormat:#"frames_%02d.png", i];
[tempArray addObject:[UIImage imageNamed:name]];
[tempArray addObject:[UIImage imageNamed:name]]; // add the frame twice
}
animatedImage.animationImages = tempArray;
edit -- The code above is intended to replace the array initialization code
animatedimage.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"frames_00.png"],
[UIImage imageNamed:#"frames_05.png"],
...

Trying to play sound with animation but keep getting "Thread 1 Signal SIGABRT" error in Xcode

My code used to work perfectly when I used to just have an animation. However, now I tried to add sound to the animation also, I've implemented the sound as well as I can however now every time the app runs it shuts down and gives me the SIGABRT error, here is my code:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController {
}
- (IBAction)Button {
AudioServicesPlaySystemSound(SoundID);
}
-(IBAction)startanimating{
animatedimage.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"ALambo1.jpg"],
[UIImage imageNamed:#"ALambo2.jpg"],
[UIImage imageNamed:#"ALambo3.jpg"],
[UIImage imageNamed:#"ALambo4.jpg"],
[UIImage imageNamed:#"ALambo5.jpg"],
[UIImage imageNamed:#"ALambo6.jpg"],
[UIImage imageNamed:#"ALambo7.jpg"],
[UIImage imageNamed:#"ALambo8.jpg"],
[UIImage imageNamed:#"ALambo9.jpg"],
[UIImage imageNamed:#"ALambo10.jpg"],
[UIImage imageNamed:#"ALambo11.jpg"],
[UIImage imageNamed:#"ALambo12.jpg"],
[UIImage imageNamed:#"ALambo13.jpg"],
[UIImage imageNamed:#"ALambo14.jpg"],
[UIImage imageNamed:#"ALambo15.jpg"],
[UIImage imageNamed:#"ALambo16.jpg"],
[UIImage imageNamed:#"ALambo17.jpg"],
[UIImage imageNamed:#"ALambo18.jpg"],
[UIImage imageNamed:#"ALambo19.jpg"],
[UIImage imageNamed:#"ALambo20.jpg"],
[UIImage imageNamed:#"ALambo22.jpg"],
[UIImage imageNamed:#"ALambo23.jpg"],
[UIImage imageNamed:#"ALambo24.jpg"],
[UIImage imageNamed:#"ALambo25.jpg"],
[UIImage imageNamed:#"ALambo26.jpg"],
[UIImage imageNamed:#"ALambo52.jpg"],
[UIImage imageNamed:#"ALambo51.jpg"],
[UIImage imageNamed:#"ALambo50.jpg"],
[UIImage imageNamed:#"ALambo49.jpg"],
[UIImage imageNamed:#"ALambo48.jpg"],
[UIImage imageNamed:#"ALambo47.jpg"],
[UIImage imageNamed:#"ALambo46.jpg"],
[UIImage imageNamed:#"ALambo45.jpg"],
[UIImage imageNamed:#"ALambo44.jpg"],
[UIImage imageNamed:#"ALambo43.jpg"],
[UIImage imageNamed:#"ALambo42.jpg"],
[UIImage imageNamed:#"ALambo41.jpg"],
[UIImage imageNamed:#"ALambo40.jpg"],
[UIImage imageNamed:#"ALambo39.jpg"],
[UIImage imageNamed:#"ALambo38.jpg"],
[UIImage imageNamed:#"ALambo37.jpg"],
[UIImage imageNamed:#"ALambo36.jpg"],
[UIImage imageNamed:#"ALambo35.jpg"],
[UIImage imageNamed:#"ALambo34.jpg"],
[UIImage imageNamed:#"ALambo33.jpg"],
[UIImage imageNamed:#"ALambo32.jpg"],
[UIImage imageNamed:#"ALambo31.jpg"],
[UIImage imageNamed:#"ALambo30.jpg"],
[UIImage imageNamed:#"ALambo29.jpg"],
[UIImage imageNamed:#"ALambo28.jpg"], nil];
[animatedimage setAnimationRepeatCount:1];
animatedimage.animationDuration = 1.2;
[animatedimage startAnimating];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *buttonURL = [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"SoundRev" ofType:#"m4a"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)buttonURL, &SoundID);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
Here is the (.h) also:
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#interface ViewController : UIViewController
{
IBOutlet UIImageView *animatedimage;
SystemSoundID SoundID;
}
-(IBAction)startanimating;
#end
I haven't used AudioServicesCreateSystemSoundID in quite a while. I suggest switching your code to use AVAudioPlayer instead. That API is both more flexible and easier to use.

Resources