I want a button to trigger the following action. When clicked it's supposed to push my logo up and out of the view and remove it. When it's clicked once more it's supposed to do the reverse thing. Meaning the image is created and pushed down back into the view. I'm using storyboard to set up my interface. My issue is that I can't get the animation to trigger. Posting my code below:
In TableViewController.h
#interface TableViewController : UITableViewController{
BOOL status;
}
#property (weak, nonatomic) IBOutlet UIImageView *animateLogo;
#property (weak, nonatomic) IBOutlet UIButton *button;
- (IBAction)onClick:(id)sender;
- (void)showHideView;
#end
In TableViewController.m
#synthesize animateLogo, button;
- (void)viewDidLoad{
[super viewDidLoad];
status = YES;
}
- (IBAction)onClick:(id)sender{
[self showHideView];
}
if(status){
[UIView
animateWithDuration:1.5
delay:0
options:UIViewAnimationCurveEaseOut
animations:^{
[animateLogo setFrame:CGRectOffset([animateLogo frame], 0, -animateLogo.frame.size.height)];
}
completion:^(BOOL completed) {}
];
status = NO;
[button setTitle:#"Show" forState:UIControlStateNormal];
}
else{
[UIView
animateWithDuration:1.5
delay:0
options:UIViewAnimationCurveEaseOut
animations:^{
[animateLogo setFrame:CGRectOffset([animateLogo frame], 0, animateLogo.frame.size.height)];
}
completion:^(BOOL completed) {}
];
status = YES;
[button setTitle:#"Hide" forState:UIControlStateNormal];
}
}
EDIT:
The animation is working if I programmatically code the UIImageView. So the issue is with the storyboard somehow. I prefer to get this working with storyboard so I can get a better overlook on the layout.
UIImage *test = [UIImage imageNamed:#"logo.png"];
animateLogo = [[UIImageView alloc] initWithImage:test];
[self.view addSubview:animateLogo];
[animateLogo setFrame:CGRectOffset([animateLogo frame], 0, animateLogo.frame.size.height)];
Problem sovled. I used a different approach were I animated the UIView instead of the UIImageView. I's now working like a charm.
Related
I need to perform a blinking effect on a image once the user click on a particular button. But my code doesn't work:
- (void)next
{
[UIView animateWithDuration:2.0f delay:0 options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{
NSLog(#"Done"); // <- USED AS COUNTER
[image setAlpha:0];
[image setAlpha:0.5];
} completion:nil];
}
What happens is my image changing its alpha to 0.5 and stops. Furthermore my console shows DONE just one time. What did I wrong?
I just created a test project and this blinked just fine...
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong)UIView *blinker;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.blinker = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
self.blinker.backgroundColor = [UIColor greenColor];
[self.view addSubview:self.blinker];
[self next];
}
- (void)next
{
[UIView animateWithDuration:2.0f delay:0 options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat animations:^{
NSLog(#"Done"); // <- USED AS COUNTER
[self.blinker setAlpha:0];
[self.blinker setAlpha:0.5];
} completion:nil];
}
With the exception that you expect the log to continue to print out in the console. So I suspect you are doing something to your image. You aren't calling self. so I am guessing it is an instance variable (ivar) and you are changing what it points to somewhere else in the code.
If you need a counter to go off every blink you may want to consider something like this...
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong)UIView *blinker;
#property (nonatomic,)NSInteger counter;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.blinker = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
self.blinker.backgroundColor = [UIColor greenColor];
[self.view addSubview:self.blinker];
[self next];
}
- (void)next
{
[UIView animateWithDuration:1.0 animations:^{
self.counter++;
NSLog(#"Counter: %#", #(self.counter));
self.blinker.alpha = 0.0;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
self.blinker.alpha = 1.0;
} completion:^(BOOL finished) {
//check to see if you want to continue blinking if so call next again
[self next];
}];
}];
}
I don't have any context as to why you want to count, but hopefully that helps.
UIView Animation isn't working in SKScene
MyScene.h
#property (nonatomic) SKLabelNode *tutorialLabel;
MyScene.m
- (IBAction)hideLabel:(id)sender {
[UIView animateWithDuration:1 animations:^(void) {
[_tutorialLabel setAlpha:0.0];
}];
}
Is there a better way to hide an SKLabelNode
If you want to fade out the label, you can use SKActions:
- (IBAction)hideLabel:(id)sender {
[_tutorialLabel runAction:[SKAction fadeOutWithDuration:1.0f]];
}
I have an UIImageView in a UITableviewCell. When it is tapped, the UIImageView should animated to be displayed fullscreen. When the image is tapped when it is fullscreen it should shrink back to the original position.
How can this be achieved?
Add a gesture recognizer to the view controller.
Add the gesture Recognizer to your header file
#interface viewController : UIViewController <UIGestureRecognizerDelegate>{
UITapGestureRecognizer *tap;
BOOL isFullScreen;
CGRect prevFrame;
}
In your viewDidLoad add this:
isFullScreen = false;
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imgToFullScreen)];
tap.delegate = self;
Add the following delegatemethod:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
{
BOOL shouldReceiveTouch = YES;
if (gestureRecognizer == tap) {
shouldReceiveTouch = (touch.view == yourImageView);
}
return shouldReceiveTouch;
}
Now you just need to implement your imgToFullScreen method.
Make sure you work with the isFullScreen Bool (fullscreen if it is false and back to old size if it's true)
The imgToFullScreen method depends on how you want to make the image become fullscreen.
One way would be:
(this is untested but should work)
-(void)imgToFullScreen{
if (!isFullScreen) {
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
//save previous frame
prevFrame = yourImageView.frame;
[yourImageView setFrame:[[UIScreen mainScreen] bounds]];
}completion:^(BOOL finished){
isFullScreen = true;
}];
return;
} else {
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
[yourImageView setFrame:prevFrame];
}completion:^(BOOL finished){
isFullScreen = false;
}];
return;
}
}
The code from #AzzUrr1, small error corrections (brackets) and tapper implemented slightly different.
Worked for me. Now it would be great to have this implemented with a scrollView, that the user can zoom in/out if the picture is bigger.. Any suggestion?
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIGestureRecognizerDelegate>{
UITapGestureRecognizer *tap;
BOOL isFullScreen;
CGRect prevFrame;
}
#property (nonatomic, strong) UIImageView *imageView;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
isFullScreen = FALSE;
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imgToFullScreen)];
tap.delegate = self;
self.view.backgroundColor = [UIColor purpleColor];
_imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 300, 200)];
_imageView.contentMode = UIViewContentModeScaleAspectFill;
[_imageView setClipsToBounds:YES];
_imageView.userInteractionEnabled = YES;
_imageView.image = [UIImage imageNamed:#"Muppetshow-2.png"];
UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imgToFullScreen:)];
tapper.numberOfTapsRequired = 1;
[_imageView addGestureRecognizer:tapper];
[self.view addSubview:_imageView];
}
-(void)imgToFullScreen:(UITapGestureRecognizer*)sender {
if (!isFullScreen) {
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
//save previous frame
prevFrame = _imageView.frame;
[_imageView setFrame:[[UIScreen mainScreen] bounds]];
}completion:^(BOOL finished){
isFullScreen = TRUE;
}];
return;
}
else{
[UIView animateWithDuration:0.5 delay:0 options:0 animations:^{
[_imageView setFrame:prevFrame];
}completion:^(BOOL finished){
isFullScreen = FALSE;
}];
return;
}
}
I ended up using MHFacebookImageViewer. Integration is easy, no subclassing UIImageView, and it also has image zooming and flick dismiss.
Although it requires AFNetworking (for loading larger image from URL), you can comment out some code (about 10 lines) to remove this dependency. I can post my AFNetworking-free version if someone needs it. Let me know :)
One possible implementation would be to use a modal view controller with UIModalPresentationFullScreen presentation style.
Just finished a version in swift, just download and add into your project:
GSSimpleImageView.swift
And usage:
let imageView = GSSimpleImageView(frame: CGRectMake(20, 100, 200, 200))
imageView.image = UIImage(named: "test2.png")
self.view.addSubview(imageView)
I create the views, UI elements etc programmatically.
I'm trying to animate views when they are added or removed. The problem is that only UIButton *button is being animated and it is animated wrong. I mean the button title comes from the top and the button itself comes from the right of the screen.
Please see the code below
AppDelegate.h
#import <UIKit/UIKit.h>
#import "TViewController.h"
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
TViewController *tv;
}
#property (strong, nonatomic) TViewController *tv;
#property (strong, nonatomic) UIWindow *window;
#end
AppDelegate.m
.....
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.window.backgroundColor = [UIColor whiteColor];
self.tv = [[TViewController alloc]initWithNibName:#"TViewController" bundle:nil];
self.window.rootViewController = self.tv;
[self.window makeKeyAndVisible];
return YES;
}
TViewController.h
#import <UIKit/UIKit.h>
#import "Elements.h"
#interface TViewController : UIViewController
{
Elements *el;
}
#property (nonatomic, retain) Elements *el;
#end
TViewController.m
-(void)loadView
{
self.view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].applicationFrame];
self.el = [[Elements alloc]
initWithNibName:#"Elements"
bundle:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:3.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view.superview cache:YES];
[self.view addSubview:self.el.view];
self.view.backgroundColor = [UIColor grayColor];
[self.view removeFromSuperview];
[UIView commitAnimations];
}
Elements.m
self.view = [[UIView alloc]initWithFrame:[UIScreen mainScreen].applicationFrame];
UILabel *howManyUsersLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 20, 300, 150)];
howManyUsersLabel.text = #"Label ...";
[self.view addSubview:howManyUsersLabel];
UIPickerView *playersPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(10, 150, 250, 100)];
playersPickerView.delegate = self;
playersPickerView.showsSelectionIndicator = YES;
[self.view addSubview:playersPickerView];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(20, 370, 280, 50);
[button setTitle:#"Button" forState:UIControlStateNormal];
[self.view addSubview:button];
Transitions have to be applied to a view that doesn't get removed or added during the transition. You are adding the transition to self.view, but then you are removing self.view during the transition.
Try adding the transition to self.view.superview instead, like this:
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view.superview cache:YES];
If that still doesn't work, are you sure this code is right:
[self.view addSubview:self.el.view];
self.view.backgroundColor = [UIColor grayColor];
[self.view removeFromSuperview];
Literally, this code is saying:
add self.el.view as a subview to self.view
set background colour of self.view to gray
remove self.view from the screen
That means the first two lines are pointless because everything you do to the view is wiped out when you remove it from the screen. And removing the view is a weird thing to do during loadView - the end result would be the view would be nil after loading.
I'm looking for some guidance on the best way to implement stock ticker style right-to-left scrolling of CALayers in Core Animation on OSX. I'm pretty new to Cocoa and don't know the best way to implement this.
I have a continuous stream of news items and stock details that I turn into CALayers (made up of 1 image and a CATextLayer) and I want to animate the CALayers from right to left of my custom view.
The news and stock information is constantly updating so I would like to add 1 item at a time to the view, scroll it right to left until the right-most point of the CALayer is showing, then add another CALayer to the view and start scrolling that as well. I would like to do this dynamic updating instead of taking a big snapshot of all my data, turning it into a big horizontal CALayer and scrolling that.
I'm looking for guidance on how to achieve this sort of effect -
do I manually animate each new CALayer along a path in the view? Or should I be using CAScrollLayer to achieve this effect?
Many thanks
Glen.
I'd do this with Quartz Composer and put a QCView in your app. It's a lot less work than you imagine.
You perhaps don't need to customize anything to do this. Here self is an object of class extending UIScrollView and with a UILabel to display the text.
////
//Header
#import <UIKit/UIKit.h>
#interface TickerScrollView : UIScrollView
- (void)displayText:(NSString *)string;
- (void)clearTicker;
#property (nonatomic, retain, readwrite) UILabel *textLabel;
#end
//////
//Implementation
#implementation TickerScrollView
#synthesize textLabel;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
// Initialization code
[self setFrame: frame];
[self setBounces: NO];
[self setShowsVerticalScrollIndicator:NO];
[self setShowsHorizontalScrollIndicator:NO];
[self setBackgroundColor:[UIColor greenColor]];
[self initialiseTextLabel];
}
return self;
}
- (void)initialiseTextLabel {
textLabel = [[UILabel alloc] initWithFrame:self.bounds];
[textLabel setTextAlignment:UITextAlignmentLeft];
[textLabel setNumberOfLines:1];
[textLabel sizeToFit];
[self addSubview:textLabel];
[self setScrollEnabled:YES];
}
- (void)displayText:(NSString *)string {
[self clearTicker];
[textLabel setText:string];
[textLabel sizeToFit];
[self beginAnimation];
}
- (void)clearTicker {
[textLabel setText:#""];
[textLabel sizeToFit];
CGPoint origin = CGPointMake(0, 0);
[self setContentOffset:origin];
}
- (void)beginAnimation {
CGFloat text_width = textLabel.frame.size.width;
CGFloat display_width = self.frame.size.width;
if ( text_width > display_width ) {
CGPoint origin = CGPointMake(0, 0);
[self setContentOffset:origin];
CGPoint terminal_origin = CGPointMake(textLabel.frame.size.width - self.frame.size.width, textLabel.frame.origin.y);
float duration = (text_width - display_width)/40;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDelay:1.0];
[UIView setAnimationDuration:duration];
[self setContentOffset:terminal_origin];
[UIView commitAnimations];
}
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (void)dealloc {
[textLabel release];
[super dealloc];
}
#end