ios simple bar graph with animation - objective-c

I need to show 2 bar graphs in my app, I dont want to use core-plot as is overkill to show just 2 bars with variant height, [UIimageView with box.png]
i have done some tests just using UIView animations, wich seem to be enough to make the bar grow or shrink, [the problem is that the height is dependant on the starting point, so my bar doesnt have a point 0 for Y, wich changes with the height for the bar]
so how could i set a point 0 for my Y axis?, so I just have to think of heigh, and not the starting point as well?
or shall i go with some bar generator framework that is not so over kill as core-plot,,
what is the simplest, lightest weight?
power-plot
ecgraph, Other?
PS. the other point is that i need to have a custom background for the chart, and custom bars thats why im using box.png for the bars]
the code...
viewDidLoad { ***
CGRect chartbackGroundImageRect = CGRectMake(150, 20, 632, 653);
UIImageView *chartbackGroundImage = [[UIImageView alloc] initWithFrame:chartbackGroundImageRect];
[chartbackGroundImage setImage:[UIImage imageNamed:#"chartArtBgnd.png"]];
chartbackGroundImage.opaque = YES; // explicitly opaque for performance
[self.view addSubview:chartbackGroundImage];
[chartbackGroundImage release];
CGRect leftBarImageRect = CGRectMake(550, 550, 81, 40);
leftBarImage = [[UIImageView alloc] initWithFrame:leftBarImageRect];
[leftBarImage setImage:[UIImage imageNamed:#"leftBar.png"]];
leftBarImage.opaque = YES; // explicitly opaque for performance
[self.view addSubview:leftBarImage];
[leftBarImage release];
***}
testBarAnimation {***
// Setup the animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.2]; //animation for arrow
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationBeginsFromCurrentState:YES];
CGRect newFrame = CGRectMake(550, 300, 81, 290);
leftBarImage.frame = newFrame;
[UIView commitAnimations];
***}
thanks a lot!

Define a utility function:
CGRect modifyRectByHeight(CGRect originalRect, CGFloat newHeight)
{
CGRect result = originalRect;
result.origin.y += height;
result.size.height += height;
return result;
}
Then use as follows:
leftBarImage.frame = modifyRectByHeight( leftBarImage.frame, 150);

I dont know, it's applicable to your project. But I used different approach, as iOS doesn't have good libraries for Chart.
I used UIWebview with HTML5 /CSS based free chart engines available on Web. For me its working fine, Bit slow than native charts would be but enough for my project

Related

Moving an Image with a button

I've got a button. After you click it, it disappears. I want to make it move a UIImageView continuously down a page with one click.
I've tried a for loop statement but the Image just drops down 200 y coordinates. This is the statement:
for (int i = 1; i <= 200; i++)
{
CGRect oldFrame = _rocketship.frame;
CGRect newFrame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y + 1, oldFrame.size.width, oldFrame.size.height);
_rocketship.frame = newFrame;
}
[self.rocketship startAnimating];
I would think that the Image would continuously go down the page, hence the for statement, but it doesn't. Is there any other way to do this?
(PS: The while loop statement does the same thing)
In IOS the screen is updated when the main thread is available and not currently running anything.
What you are doing is not going to work ever. All you are doing is setting the views position to off the screen because the for loop will finish before the vote is updated.
What you need to do is use core animation.
There is a class method on UIView that starts with "aninateWithDuration". There are several different methods.
These are the methods that you need to use in order to animate anything in IOS.
I can't answer with code at the moment as I'm on a mobile but check the docs for UIView. It will have documentation for these animation methods.
The method is...
[UIView animateWithDuration:1.0
animations:^{
// set the end position here
}];
Also I have a feeling that you will probably have auto layout on. If so let me know because there are different ways of animating if that is the case.
Try something like this instead:
[UIView animateWithDuration:1.0 animations:^{
CGRect oldFrame = _rocketship.frame;
CGRect newFrame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y + 200, oldFrame.size.width, oldFrame.size.height);
_rocketship.frame = newFrame;
}];
Josue Espinosa is almost correct
[UIView animationWithDuration:1.0{
CGRect oldFrame = _rocketship.frame;
CGRect newFrame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y + 1, oldFrame.size.width, oldFrame.size.height);
_rocketship.frame = newFrame;
but you probably want to move the image more then 1 pixel. the way this work is that this will animate the movement to the new location from point A to point B taking the time duration. in the code above it will take 1 second to move the button from point A to point B so say you want to move the button down 200 pixel the coude should be:
[UIView animationWithDuration:1.0
animations:^{
CGRect oldFrame = _rocketship.frame;
CGRect newFrame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y + 200, oldFrame.size.width, oldFrame.size.height);
_rocketship.frame = newFrame;
}];
this will basically animate any visual change you set as being the end result. from state A to state B.

How to Generate a Shockwave Effect

I would like to generate a shockwave effect when I tap on a circular UIView. The effect I'm looking for is very similar to 'Circadia' on the App Store.
(source: mzstatic.com)
Note the circular line that is expanding from the centre view. I couldn't find any kind of tutorial, so I tried the effect using a cheat:
-(void)startShockwave:(UIView *)target
{
// Replace the view tapped with one that will expand
UIView *wave = [[UIView alloc]initWithFrame:target.frame];
wave.backgroundColor = target.backgroundColor;
wave.alpha = 0.5;
wave.layer.masksToBounds = YES;
wave.layer.cornerRadius = wave.frame.size.width / 2;
// Hide it below the original view
[self.view insertSubview:wave belowSubview:target];
CGRect frame = wave.frame;
// Create a view that is the same colour as self.view to make it look like a hole
UIView *center = [[UIView alloc]initWithFrame:CGRectMake(frame.origin.x + 10, frame.origin.y + 10, frame.size.width - 20, frame.size.height - 20)];
center.backgroundColor = self.view.backgroundColor;
center.layer.masksToBounds = YES;
center.layer.cornerRadius = center.frame.size.width / 2;
[self.view insertSubview:center aboveSubview:wave];
// Hide the original view
target.alpha = 0;
// IMPORTANT: I send these views behind the others so that center does not overlap them
[self.view sendSubviewToBack:center];
[self.view sendSubviewToBack:wave];
[UIView animateWithDuration:0.4 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
CGAffineTransform waveTransform = wave.transform;
CGAffineTransform centerTransform = center.transform;
// Expand the views to look like a shockwave
wave.transform = CGAffineTransformScale(waveTransform, 4, 4);
center.transform = CGAffineTransformScale(centerTransform, 5.75, 5.75);
// Fade the wave out to nothing
wave.alpha = 0;
} completion:^(BOOL finished) {
// Remove the shockwave
[wave removeFromSuperview];
[center removeFromSuperview];
}];
}
This works quite well...
...With only one shockwave. However, when they intersect, one center overlaps the other due to the most recent shockwave being sent to the back.
I would prefer intersecting shockwaves to be more like this:
I'm not sure how to create this type of effect, however, so any help is much appreciated!
Use [UIColor clearColor] to make the center of your circle transparent (so you can see interface elements residing beneath it).
center.backgroundColor = [UIColor clearColor];
It's a quick fix! You already did most of it. Just change this line:
center.backgroundColor = self.view.backgroundColor;
to
center.backgroundColor = [UIColor clearColor];

iOS Cross Dissolve WITHOUT a darker middle

We are trying to do a dissolve between two almost exact images (almost animation frames) but so far we cannot remove the darkening that happens midway through the dissolve. The client is very firm about not having this darker dissolve, anything thought?
UIImageView *newImageView = [[UIImageView alloc] initWithFrame:imageViewSmileDesign.frame];
newImageView.image = imageViewSmileDesign.image;
[self.view addSubview:newImageView];
imageViewSmileDesign.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#.jpg", result]];
imageViewSmileDesign.alpha = 0;
[UIView animateWithDuration:0.5 animations:^{
imageViewSmileDesign.alpha = 1;
newImageView.alpha = 0;
} completion:^(BOOL finished) {
[newImageView removeFromSuperview];
} ];
Thanks for looking.
You could use the cross-disolve animation that's built into UIView:
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion
Set options to UIViewAnimationOptionTransitionCrossDissolve.
Just don't change the alpha of 'newImageView' to 0. This will cause the new image to fade on top of the old one, and you don't have this half-way state where they are both semi-transparent revealing the background color.
You will have to bring imageViewSmileDesign to the front with a call to bringSubviewToFront: before the animation.
If both images have the same frame, just remove newImageView.alpha = 0;. That'll do the trick.
You need to delay the START of the newImageView.alpha fade.

List examples of how to "briefly draw attention" to an object on screen in iOS?

In iOS, how can one briefly draw attention to an object on screen? Suppose, create a brief glow or cause a shadow to appear and then disappear?
For the purposes of this question, let's define "object on screen" as an instance of UIImageView.
Also, if possible provide an example of how to draw attention to a button.
Most people list code, but I'm sticking to describing some examples;
I've seen objects briefly grow and shrink back to their normal size to draw attention
Bejeweled (a Popcap game) lets diamonds briefly 'shine' (as if sunlight passed over it) to give you a subtle hint
I've seen certain applications use a hand or a fictive character point to a certain object briefly
And of course, you could always introduce a talking paperclip to tell you what's what.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.1f];
yourView.transform = CGAffineTransformMakeScale(1.1, 1.1);
[UIView commitAnimations];
Or, of course the same thing with a block animations. And after the attention got away from your view you can use :
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.1f];
yourView.transform = CGAffineTransformIdentity;
[UIView commitAnimations];
Here is a simple hop animation...
- (void)drawAttn
{
float jumpHeight = 20.0;
CGPoint originalPoint = objectForAttn.center;
CGPoint jumpPoint = CGPointMake(objectForAttn.center.x, objectForAttn.center.y - jumpHeight);
[UIView animateWithDuration:0.20 delay:0.0 options:UIViewAnimationOptionAutoreverse animations:^{
[objectForAttn setCenter:jumpPoint];
} completion:^(BOOL finished) {
/* do other stuff after hop */
}];
}
My app QCount (free in the store, tap a "wrong" number 3 times) uses a fade animation as follows:
(note I wrote this when I was REALLY new to iOS, so there is probably a more compact way to write it)
aLabel = // a UILabel I get from somewhere
aColor = aLabel.backgroundColor;
[UIView animateWithDuration:0.2
delay: 0.0
options: UIViewAnimationOptionCurveEaseOut
animations:^{
aLabel.alpha = 0.0;
}
completion:^(BOOL finished){
// Wait .2 seconds and then fade in the view
[UIView animateWithDuration:.2
delay: 0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
aLabel.alpha = 1.0;
}
completion:nil];
}];
There are lots of options: hopping, underlining, vibrating, blinking, rotating, scaling, endarkening around, and their combinations.
But IMO, shine effect on "slide to unlock" text is excellent.
You can check it out here:
iPhone "slide to unlock" animation
I wanted to draw attention to a label whose value had changed. This simple animation produces a nice 'I've changed' animation...
//copy the label
UILabel *newPageLabel = [[UILabel alloc] initWithFrame:_countLabel.frame];
[newPageLabel setFrame:CGRectOffset(newPageLabel.frame, 0, 0)];
newPageLabel.text = _countLabel.text;
newPageLabel.textAlignment = _countLabel.textAlignment;
newPageLabel.backgroundColor = _countLabel.backgroundColor;
newPageLabel.textColor = _countLabel.textColor;
newPageLabel.font = _countLabel.font;
//scale and fade out the copied label
[self.navigationController.toolbar addSubview:newPageLabel];
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionLayoutSubviews
animations:^{
newPageLabel.transform = CGAffineTransformMakeScale(2,2);
newPageLabel.alpha = 0;
}
completion:^(BOOL finished){
[newPageLabel removeFromSuperview];
}
];

How can I program a custom partial or sub view for a calculator?

I'm building a basic calculator app. The calculator is already fully functional with basic features. The problem I'm having is I ran out of room on the screen to add other, more advanced features. Ideally what I would like to do is create some kind of subclass and view that slides up to to the bottom of the label (where the completed calculations are displayed), when a button on the bottom of the screen is pressed. In other words, I want a view with more operators and computation options to slide up to the bottom of the label and I dont want this view to cover up any digits that are being displayed in the label. Is there anyway to achieve this?
Yes, you can. When your button is pressed, create your new view (with the extra functions), add it as a subview to self.view, and animate a change to it's frame, so that it's frame changes from below the visible view to just below your digits.
Like this:
-(void) buttonPressed {
UIView *myNewView = << create your view >>
myNewView.frame = CGRectMake(0,480, 320,200); // or whatever your width and height are
// 480 means it will be below the visible frame.
[self.view addSubview: myNewView];
float bottom_Y_of_digit_display = 100;// or wherever it is...
[UIView beginAnimations:nil contenxt:nil];
[UIView setAnimationDelay: 0.0];
[UIView setAnimationDuration: 1.0]; // one second.
myNewView.frame = CGRectMake(0,bottom_y_of_digit_display, 320,200);
[UIView commitAnimations];
}
You can use UIAnimations to create an animation out of any changes to UIView properties. You can make your UIView hidden by settings its frame.origin.y to 480 and then change the rect and wrap it in a UIAnimation.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
[UIView commitAnimations];
UPDATE
If you are targeting iOS 4.0 and later then you should use the new UIAnimations interface.
UIViewAnimationOptions options = UIViewAnimationOptionCurveLinear;
[UIView animateWithDuration:0.75 delay:0 options:options
animations:^(){
CGRect newFrame = newSubView.frame;
newFrame.origin.y -= newSubView.frame.size.height;
newSubView.frame = newFrame;
}
completion:^(BOOL finished){
//Do something upon completion
}];