. So it will show the image of random 1-6 image of the dice on the button by touching the UIButton with a IBAction using a array and a random() to select from the array of images to desplay on the image background
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (IBAction)diceButton:(UIButton *)sender {
_diceArray=[NSMutableArray arrayWithObjects:
[UIImage imageNamed:#"Dice_1.png"],
[UIImage imageNamed:#"Dice_2.png"],
[UIImage imageNamed:#"Dice_3.png"],
[UIImage imageNamed:#"Dice_4.png"],
[UIImage imageNamed:#"Dice_5.png"],
[UIImage imageNamed:#"Dice_6.png"],nil];
int index = random() % 5 ;
for (int i = 0; i < [_diceArray count]; i++) {
[_diceButton setBackgroundImage:[UIImage imageNamed:[_diceArray objectAtIndex:index]] forState:UIControlStateNormal];
}
}
#end
Use like this
[_diceButton setBackgroundImage:_diceArray[index] forState:UIControlStateNormal];
Since your _diceArray contains UIImage's not image names
hi you have two way to correct this program, first one change your
array to
_diceArray=[NSMutableArray arrayWithObjects:
#"Dice_1.png",
#"Dice_2.png",
#"Dice_3.png",
#"Dice_4.png",
#"Dice_5.png",
#"Dice_6.png",nil];
or change
[_diceButton setBackgroundImage:[_diceArray objectAtIndex:index] forState:UIControlStateNormal];
You are storing UIImage objects in the array so you can't call
[UIImage imageNamed:[_diceArray objectAtIndex:index]
So you need to use:
[_diceButton setBackgroundImage:[_diceArray objectAtIndex:index] forState:UIControlStateNormal];
My Suggestion : use setImage: instead of setBackgroundImage:
for (int i = 0; i < [_diceArray count]; i++)
{
[_diceButton setImage:[_diceArray objectAtIndex:index] forState:UIControlStateNormal];
[_diceButton setImage:[_diceArray objectAtIndex:index] forState:UIControlStateNormal];
}
Related
I need to change background image of button several times, I would like to use sequence of images to change background on click but I couldn't find any Swift documentation.
Maybe someone knows how to do that ?
This is one of the way.
NSMutableArray *imageArray = [NSMutableArray new];
for (int i = 1; i < 4; i ++) {
[imageArray addObject:[UIImage imageNamed:[NSString stringWithFormat:#"%d.png",i]]];
}
[myButton setImage:[UIImage imageNamed:#"1.png"] forState:UIControlStateNormal];
[myButton.imageView setAnimationImages:[imageArray copy]];
[myButton.imageView setAnimationDuration:0.5];
[myButton.imageView startAnimating];
Call startAnimating method in on click method.
In Swift:
var imageArray = [UIImage]()
for var index = 0; index < num; ++index {
imageArray.append( UIImage(named: "imageNumber\(index)" )! )
}
myButton.setImage( UIImage(named: "imageNumber1")! ), forState: .Normal)
myButton.imageView!.animationImages = imageArray
myButton.imageView!.animationDuration = 1.0
myButton.imageView!.startAnimating()
I am using the below code to change the UIImageView's image after a short duration. The images being used are stored in an array as you can see.
The problem is, no matter what 'duration' or 'delay' I set, the imageview changes almost instantly to the last image in the array.
Should I instead be using the main thread to add a delay between each image transition?
////////////////////////////////////////////////////////////////
animationCount = 0;
imageArray =[NSMutableArray new];
[imageArray addObject:[UIImage imageNamed:#"gauge1final.png"]];
[imageArray addObject:[UIImage imageNamed:#"gauge2final.png"]];
[imageArray addObject:[UIImage imageNamed:#"gauge3final.png"]];
[imageArray addObject:[UIImage imageNamed:#"gauge4final.png"]];
[imageArray addObject:[UIImage imageNamed:#"gauge5final.png"]];
[self multiStageAnimate];
////////////////////////////////////////////////////////////////
-(void) multiStageAnimate{
[UIView animateWithDuration:5.0
delay:5.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^
{
self.gauge.image = [imageArray objectAtIndex:animationCount];
}
completion:^(BOOL finished){
animationCount ++;
if(animationCount < imageArray.count){
[self multiStageAnimate];
}
else
{
animationCount = 0;
}
}];
}
UIImageView does have a mechanism to accomplish your need.
UIImageView *imageView = [[UIImageView alloc] init];
imageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"image1"],
[UIImage imageNamed:#"image2"],
[UIImage imageNamed:#"image3"], nil];
imageView.animationRepeatCount = 0; // 0 means repeat without stop.
imageView.animationDuration = 1.5; // Animation duration
[imageView startAnimating];
If you are using multiple screens with the same animation, it's better to create one .plist file and then use this anywhere in your project. The steps are as follows:
First, generate one .plist file File-> New File-> Resource ->Property List
Write your code like this:
ViewController.h
#property (weak, nonatomic) IBOutlet UIImageView *dataImageView;
ViewController.m
NSDictionary *picturesDictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"PhotesArray" ofType:#"plist"]];
NSArray *imageNames = [picturesDictionary objectForKey:#"Photos"];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (int i=0; i<[imageNames count]; i++) {
[images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
//Normal animation
self.dataImageView.animationImages = images;
self.dataImageView.animationDuration = 5.0;
[self.dataImageView startAnimating];
The image property of a UIImageView won't animate. What you need to do is have 2 UIImageView widgets one on top of another. Then, you can animate their alpha properties from 0 to 1 (and vice-versa) with each transition.
So basically I am making an API call to retrieve a list of Charities. I then place all this in an array and set UIButtons dynamically.
I then allow the user to select the charity and display a view with that index's data.
My loop is here;
for (int i = 0; i < [self.imageArray count]; i++) {
NSDictionary *listRoles = [self.imageArray objectAtIndex:i];
NSString *charityName = [listRoles objectForKey:#"name"];
NSString *charityDescription = [listRoles objectForKey:#"description"];
NSString *charityImage = [listRoles objectForKey:#"image"];
UIImage *pImage=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:charityImage]]];;
UIButton *button = [[UIButton alloc] initWithFrame:frame];
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[button setImage:pImage forState:UIControlStateNormal];
[button setTag:i];
[self.scrollView addSubview:button];
I then have a clicked method;
- (void)buttonClicked:(UIButton*)button
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
CharityProfileViewController *cpvc = [storyboard instantiateViewControllerWithIdentifier:#"CharityProfile"];
[self presentViewController:cpvc animated:YES completion:nil];
}
How can I retrieve the index, I know that I could set random tags for the UIButton but how would I still know which one?
You can set the tag value of button as
[button setTag:i+1];
then in Button Action
- (void)buttonClicked:(UIButton*)button
{
NSLog(#"Button Tag : %d",button.tag);
NSLog(#"Selected Index Object : %#",[self.imageArray objectAtIndex:button.tag-1]);
}
You can either retrieve the a tag for your button by button.tag or add your buttons to an array and use then [buttonsArray indexOfObject:button] in your buttonClicked: method
When app launches I add UIImageViews to screen with no image. Then I load image one by one using NSThread and set it for those views. The UiImageViews remain blank until after all images have been loaded and the thread finishes. Why doesn't the image show as soon as I set it for the UIImageView, why does it wait for NSThread to end?
To add image views :
for(i = value; i < val; i++){
UIButton *newbutton = [UIButton buttonWithType:UIButtonTypeCustom];
[newbutton setBackgroundColor:[UIColor whiteColor]];
UIImageView *newback = [[UIImageView alloc] init];
newback.contentMode = UIViewContentModeScaleAspectFit;
[newback setFrame:CGRectMake(0, 0, 140, 140)];
[newbutton addSubview:newback];
height = MIN(300, newSize.height);
[newbutton setFrame:CGRectMake(currentX, currentY, width, height)];
newbutton.layer.cornerRadius = 10;
newbutton.clipsToBounds = YES;
[newbutton addTarget:self action:#selector(processButtonClick:) forControlEvents:UIControlEventTouchUpInside];
}
To add images in a thread I call a function which does following :
for(i = value; i < val; i++){
UIImage *newimage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#“http://test.com/a.jpg”, hash]]]];
UIButton *newbutton = (UIButton*)[self.subviews objectAtIndex:i];
[((UIImageView*)[newbutton.subviews objectAtIndex:0]) newimage];
}
Generally speaking, UIKit is not thread-safe. Fetch data from URL in a background thread and set the image in the main thread.
EDIT:
In your main thread do something like
dispatch_async(someDispatchQ, ^{
[self functionToGetData];
});
and inside functionToGetData do
for(i = value; i < val; i++){
NSData *data = //get Data
UIImage *newImage = //make image from data
dispatch_async(dispatch_get_main_queue(), ^{
[imageView setImage:newImage];
});
}
This will ensure that you are using a background thread to fetch data/make image and using the main thread to set the image. This also eliminates the need to use a timer to constantly poll the background thread since the background thread automatically dispatches image-setting to the main thread as soon as an image is received.
use-
import class ImageDownloader.h & .m
link-> https://github.com/psychs/imagestore/tree/master/Classes/Libraries/ImageStore
//Now use this method to download
-(void)downloadImageWithURL:(NSString *)url{
if(self.downloder)return; //If already downloading please stay away
url=[NSString stringWithFormat:#"%#%0.0fx%0.0f/%#/%#",IMAGE_ENDPOINT,self.imgViewExhibitors.frame.size.width,self.imgViewExhibitors.frame.size.height,#"fit",[ImagePath forURLString:url]];
self.downloder=[[ImageDownloader alloc] init];
self.downloder.delegate=self;
self.downloder.indicator=self.indicator;
[self.downloder downloadImageWithURL:url];
}
-(void)imageDownloaded:(UIImage *)image forIndexPath:(NSIndexPath *)indexPath{
if(image){
//Put the downloaded image in dictionary to update while scrolling
//[self.speakerData setObject:image forKey:#"image"];
self.imgViewExhibitors.image=image;
}
}
A simple fix would be
for(i = value; i < val; i++){
UIImage *newimage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#“http://test.com/a.jpg”, hash]]]];
UIButton *newbutton = (UIButton*)[self.subviews objectAtIndex:i];
// this ensures that the UI update (setting the image) is done on the main thread.
// This is important for the UI to update properly.
dispatch_async(dispatch_get_main_queue(), ^{
[((UIImageView*)[newbutton.subviews objectAtIndex:0]) setImage:newimage];
}
}
I have this simple function where i sap rate the button animation and then start animation for every button but i dont know why only one button animate not others which clicked, please help me with this
- (IBAction)startAnimation:(UIButton *)button {
NSMutableArray* imagesArray = [[NSMutableArray alloc] init];
for (int images = 0; images < 15; images++) {
UIImage* buttonImage = [UIImage imageNamed:[NSString stringWithFormat:#"aaqqq00%02d.png", images]];
[imagesArray addObject:buttonImage];
}
NSArray* reversedAnim = [[imagesArray reverseObjectEnumerator] allObjects];
int buttonTag = button.tag;
animButton.adjustsImageWhenHighlighted = NO;
for (int images = 0; images < 15; images++) {
UIButton *animButton = (UIButton *)[self.view viewWithTag:buttonTag];
if (images <= buttonTag) {
animButton.imageView.animationImages = imagesArray;
[animButton setImage:
[UIImage imageNamed:#"aaqqq0014.png"] forState:UIControlStateNormal];
} else {
animButton.imageView.animationImages = reversedAnim;
[animButton setImage:
[UIImage imageNamed:#"aaqqq0000.png"] forState:UIControlStateSelected];
}
NSLog(#"%#", animButton.imageView.animationImages);
animButton.imageView.animationDuration = 1; //whatever you want (in seconds)
animButton.imageView.animationRepeatCount = 1;
[animButton.imageView startAnimating];
}
}
You're passing the button, so doing the tag lookup seem pointless and error prone (if there are multiple views with the same tag in the hierarchy).
Setting the buttons image view animation images (animButton.imageView.animationImages) and then after that setting a single image ([animButton setImage:...) is also pointless.
What does your log statement say about the animation images?