Animating a button to look like a spinner on click - iphone

So basically I have a button. When it is clicked the first time I want it to display a spinner animation (kind of like the game twister, the spinner thing). I want this animation on the button itself. Preferably as the background. I have the other part of the button working correctly where when it is pressed again it stops pointing in a direction at random. Any ideas on how to get this working?
-(IBAction)spinnerButton:(id)sender{
NSString *display;
if (pressCount%2 == 0) {
NSString *spinning;
spinning = #"Press again to stop spinner.";
display = [[NSString alloc] initWithFormat:#"%#",spinning];
sender.animationImages = [NSArray arrayWithArray: imageArray];
sender.animationDuration = 1.0;
sender.animationRepeatCount = 0;
sender.startAnimating;
}
The imageArray is put together here.
- (void)viewDidLoad
{
[super viewDidLoad];
imageArray = [[NSMutableArray alloc] initWithCapacity:8];
for (int i = 0; i < 8; i++) {
[imageArray addObject:[UIImage imageNamed:[NSString stringWithFormat:#"piece%d.png", i]]];
}
}
My thought is that it needs to look something like this
[sender setBackgroundImage:[UIImage imageNamed:#"piece1.png"] forState:UIControlStateNormal];
but I'm not exactly sure how to place the array in it and make set the duration and all that stuffs. Thanks any help is welcomed and appreciated.

I got it to work fine. I placed an Image View over the top of the button. It still allowed me to click the button and it allowed me to tie the images and animation in correctly.

Related

IOS Scrollview Marquee style

I have a set of 4 images that i want to show in a UIScrollView. This scroll view contains ad banners. So they have to keep scrolling vertically down automatically similar to marquee effect - user does not need to touch the screen to scroll.This process should keep repeating.
If the user touches the screen, the scrolling should stop & when user re-touches the screen the scrolling should restart from where it had left.
There is as simpler way, I guess. UIImageView can help you. Follow these Steps :
1) Add 4 UIImageViews Vertically Down.
2) Create 4 Different Arrays for these ImageViews.
NSArray *frames1 = [NSArray arrayWithObjects:[UIImage imageWithName:#"a.png"],[UIImage imageWithName:#"b.png"],[UIImage imageWithName:#"c.png"],[UIImage imageWithName:#"d.png"],nil];
NSArray *frames2 = [NSArray arrayWithObjects:[UIImage imageWithName:#"b.png"],[UIImage imageWithName:#"c.png"],[UIImage imageWithName:#"d.png"],[UIImage imageWithName:#"a.png"],nil];
NSArray *frames3 = [NSArray arrayWithObjects:[UIImage imageWithName:#"c.png"],[UIImage imageWithName:#"d.png"],[UIImage imageWithName:#"a.png"],[UIImage imageWithName:#"b.png"],nil];
NSArray *frames4 = [NSArray arrayWithObjects:[UIImage imageWithName:#"d.png"],[UIImage imageWithName:#"a.png"],[UIImage imageWithName:#"b.png"],[UIImage imageWithName:#"c.png"],nil];
3) Provide these Arrays to all these different ImageViews.
yourImageView1.animationImages = frames1;
yourImageView2.animationImages = frames2;
yourImageView3.animationImages = frames3;
yourImageView4.animationImages = frames4;
4) You can add some Effects also...
// all frames will execute in 1.75 seconds
yourImageView.animationDuration = 1.75;
// repeat the annimation forever
yourImageView.animationRepeatCount = 0;
5) Simply startAnimating the ImageViews.
[yourImageView1 startAnimating];
[yourImageView2 startAnimating];
[yourImageView3 startAnimating];
[yourImageView4 startAnimating];
6) You can always use -touchesEnded method to start and stop Animation.
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if ([[touches anyObject] view] == yourImageView1) {
//Here you can write the code to stop and start Animation of UIImageView
}
}
I think this will give you the effect what you want.
GoodLuck !!!
This is how I have done it finally :-) .
Call the below method from viewDidLoad
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(scrollTheScrollView) userInfo:nil repeats:YES];
Now implement the method
-(void)scrollTheScrollView{
static int i=0;
i++;
if(self.scrollView.contentOffset.y == 700.0)//This 700.0 will be different for you
i=0;
NSLog(#"Content offset in scrolling method is %#",self.scrollView);
[self.scrollView setContentOffset:CGPointMake(0, i*5)];}
I made an API for this, if you're interested.
https://github.com/dokun1/DOMarqueeLabel

Access NSMutableArray created in viewDidLoad on button tap

In my app I have an animation that plays when the user taps a button. In the IBAction method for the button tap, I am having it create a NSMutable Array, load the images into the array, then cycle through the images.
This results in a fair amount of lag between the button tap and the animation playing, but every tap after that is fine since the array is already created with the images.
I have tried placing the array creation and image loading in the vieDidLoad method, but for some reason the IBAction method (where the call to cycle through the images is) cannot access the array. How would I make the array available to it?
- (IBAction)tap {
NSMutableArray *anim = [[NSMutableArray alloc]initWithObjects:[UIImage imageNamed:#"0001.png"], ...(x30)... nil];
type.animationImages = anim;
type.animationDuration = 1.0;
type.animationRepeatCount = 1;
[type startAnimating];
}
Define NSMutableArray *anim into your UIViewController .h file. It will make it available to global to access anywhere into your .m file.
- (void) viewDidLoad
{
anim = [[NSMutableArray alloc]initWithObjects:[UIImage imageNamed:#"0001.png"], ...(x30)... nil];
}
- (IBAction)tap
{
type.animationImages = anim;
type.animationDuration = 1.0;
type.animationRepeatCount = 1;
[type startAnimating];
}
Define NSMutableArray *anim in .h file ie class member variable
in viewDidLoad method defin like this:
anim = [[NSMutableArray alloc]initWithObjects:[UIImage imageNamed:#"0001.png"], ...(x30)... nil];
Use like this in button event:
- (IBAction)tap
{
type.animationImages = anim;
type.animationDuration = 1.0;
type.animationRepeatCount = 1;
[type startAnimating];
}
Try this simple code may be it help full for you.
Array allocate one time when you tap first time.
if(!anim)
{
NSMutableArray *anim = [[NSMutableArray alloc]initWithObjects:[UIImage imageNamed:#"0001.png"], ...(x30)... nil];
NSLog(#"array allocate");
}else
{
NSLog(#"array already allocated");
}

Tapping button to go through each frame of animation

I am trying to create an app where when you tap a button it will go to the next frame in an animation.
I have 8 image files, and when I press the button I want the 1st image to display, and when i press the button again, I want the 2nd image to replace the 1st image and so on.
I was thinking something like:
-(IBAction)buttonPressDoStuff:(id)sender {
imageThing.image = [UIImage imageNamed:#"image1.png"];
imageThing.image = [UIImage imageNamed:#"image2.png"];
imageThing.image = [UIImage imageNamed:#"image3.png"];
imageThing.image = [UIImage imageNamed:#"image4.png"];
}
and somehow making this all work consecutively with each press.
I am fairly new at objective c, so any help would be much appreciated.
Can anyone throw up some sample code to do this?
Let's think about this. If you want to do something sequentially, that sounds like the job of an array. So what do you think about this:
In your .h file, add these instance variables:
NSMutableArray* picturesArray;
NSInteger counter;
And now in your .m file, in your class' init method:
//this loop will fill your array with the pictures
for(int idx = 0; idx < NUMBER_OF_PICTURES; idx++) {
//IMPORTANT: this assumes that your pictures' names start with
//'image0.png` for the first image, then 'image1.png`, and so on
//if your images' names start with 'image1.png' and then go up, then you
//should change the 'int idx = 0' declaration in the for loop to 'int idx = 1'
//so the loop will start at 0. You will then need to change the condition
//to 'idx < (NUMBER_OF_PICTURES + 1)' to accomodate the last image
NSString* temp = [NSString stringWithFormat:#"image%i.png", idx];
UIImage* tempImage = [UIImage imageNamed:temp];
[picturesArray addObject:tempImage];
}
and in your buttonPressDoStuff: method:
//this method will move to the next picture in the array each time it is pressed
-(IBAction)buttonPressDoStuff:(id)sender {
if(counter < [pictureArray count]) {
imageThing.image = [picturesArray objectAtIndex:counter];
counter++;
}
}
Your init method should look something like this:
- (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) {
//do setup here
for(int idx = 0; idx < NUMBER_OF_PICTURES; idx++) {
NSString* temp = [NSString stringWithFormat:#"image%i.png", idx];
UIImage* tempImage = [UIImage imageNamed:temp];
[picturesArray addObject:tempImage];
}
}
//it is important that you return 'self' no matter what- if you don't,
//you will get the 'control reached end of non-void method' warning
return self;
}

Hiding or moving SegmentContoller

Hello I've tried for 3 weeks to solve this issue and it stumps me. What i am trying to do is create a 3 part segment from an array, display it in a view in a certain position, then remove it from view when the "OFF" flag is set. Every thing works except the removal of the segment. It will even commuticate with (pickOne) and display the segment letters in a label. What i can't get to work is either of the two: setHidden:YES, or removeAllSegments. Any help would be appreciated. Here is my code.
- (void) showSegment {
int x = 192;
int y = 212;
int w = 125;
int h = 25;
SegUnit1 = #"A";
SegUnit2 = #"B";
SegUnit3 = #"C";
threeSegs = [NSArray arrayWithObjects: SegUnit1, SegUnit2, SegUnit3, nil];
segSize = [NSArray arrayWithArray:threeSegs];
UISegmentedControl *heightSC = [[UISegmentedControl alloc] initWithItems:segSize];
if ([segmentState_height isEqualToString:#"ON"]) {
NSLog(#"segmentState_height = %#",segmentState_height);
heightSC.frame = CGRectMake(x, y, w, h);
heightSC.segmentedControlStyle = UISegmentedControlStyleBar;
heightSC.selectedSegmentIndex = -1;
[heightSC addTarget:self
action:#selector(pickOne:)
forControlEvents:UIControlEventValueChanged];
[self.view addSubview:heightSC];
[heightSC release];
} else if ([segmentState_height isEqualToString:#"OFF"]) {
NSLog(#"segmentState_height = %#",segmentState_height);
[heightSC setHidden:YES]; // NSLog showing "OFF" but segment will not hide.
[heightSC removeAllSegments]; // NSLog showing "OFF" and segment is suppose to dismantle and does not.
}
}
I know now that i have to "not" create and remove in the same function, and was given a tip on correcting this but I don't know how to use the tip.
here is what was suggested.
Well, your method is a little confused, since you are trying to both create and hide at the same time. So you might consider splitting that up into separate methods.
In general, it will be along these lines:
Code:
if ([self theControlProperty] == nil)
{
UISeg... *theControl = [[UISeg alloc] ....];
[self setTheControlProperty:theControl];
...
}
if (shouldHideTheControl)
{
[[self theControlProperty] setHidden:YES];
}
Any help would be appreciated.
The problem you have is that you're creating a new UISegmentedControl instance every time that method is called. The first time through, you create an instance and add it as a subview to your view. This apparently works fine, as it should. Then the method returns, and you no longer have any easy way to refer to that instance that you created. When you re-enter -showSegment, you create a different instance, and then hide and/or destroy it. This different instance has no effect whatsoever on the instance that you gave to the view.
What you need to do is make heightSC an instance variable. Add it to the interface declaration in the header file, then initialize it only once, and hide or modify it as needed subsequently. The key point is that you need to have a reference to the instance of the UISegmentedControl which is being drawn on the screen, a reference that lives outside the method itself that you can use the second, third, fourth, etc time you call that method.
Try using the remove segments in your button choice method pickOne. This takes it outside the showSegment method and matches the users desired action to make the change and clear off the buttons.
- (void) pickOne:(id)sender {
UISegmentedControl* userChose = sender;
if( [userChose selectedSegmentIndex] == 0 ){
your first button operation;
[heightSC removeAllSegments];
}
if( [userChose selectedSegmentIndex] == 1 ){
your second button operation;
[heightSC removeAllSegments];
}
if( [userChose selectedSegmentIndex] == 2 ){
your third button operation;
[heightSC removeAllSegments];
}
}
I tried this and got the results I was looking for. Thanks goes to Mythogen and BrianSlick I just need to check and make sure there are no leaks. Now that will be a task.
Does anyone know if I need the second [heightSC release]; ?
// .h
# interface ------ {
UISegmentedControl *segmentPicked;
}
|
#property (nonatomic, retain) UISegmentedControl *segmentPicked;
// .m
|
#synthesize segmentPicked;
|
if ([self segmentPicked] == nil) {
UISegmentedControl *heightSC = [[UISegmentedControl alloc] initWithItems:segSize];
[self setSegmentPicked:heightSC];
[heightSC release];
heightSC.frame = CGRectMake(x, y, w, h);
heightSC.segmentedControlStyle = UISegmentedControlStyleBar;
heightSC.selectedSegmentIndex = -1;
[heightSC addTarget:self
action:#selector(pickOne:)
forControlEvents:UIControlEventValueChanged];
[self.view addSubview:heightSC];
[heightSC release];
}
if ([segmentState_height isEqualToString:#"OFF"])
{
[[self segmentPicked] setHidden:YES];
} else {
[[self segmentPicked] setHidden:NO];
}
[yourSegment removeFromSuperview];
?

How to change Pagecontroller indicator color from default white?

http://apptech.next-munich.com/2010/04/customizing-uipagecontrols-looks.html
In the above url has some sample code for customizing UIPageControl's Looks...
In my application i want to change the pagecontrol indicator(dot) color to some other color instead of default white...I'm following the code that are given in the above link.But,i'm having doubt.
NSString* imgActive = [[NSBundlemainBundle] pathForResource:IMG_PAGE_ACTIVE ofType:nil];
NSString* imgInactive = [[NSBundlemainBundle] pathForResource:IMG_PAGE_INACTIVE ofType:nil];
what should i give for pathForResource:-------------.and where should i add the images for active and inactive pages and how to retrieve the image into application.
please give me some ideas to do this...
Thanks in Advance
Just add the two images to your project resources.
For example dot_active.png and dot_inactive.png.
NSString* imgActive = [[NSBundlemainBundle] pathForResource:#"dot_active" ofType:#"png"];
NSString* imgInactive = [[NSBundlemainBundle] pathForResource:#"dot_inactive" ofType:#"png"];
I use these two images:
for the active dot
for the inactive dots
EDIT
If you want to modify the size of the dots, maybe
for (NSUIntegersubviewIndex = 0; subviewIndex < [self.subviews count]; subviewIndex++) {
UIImageView* subview = [self.subviews objectAtIndex:subviewIndex];
if (subviewIndex == page) {
[subview setImage:[UIImage imageWithContentsOfFile:imgActive]];
} else {
[subview setImage:[UIImage imageWithContentsOfFile:imgInactive]];
}
subview.frame = CGRectMake(/* position and dimensions you need */);
}
should do the trick.