scrollViewDidEndDecelerating not executing - iphone

I can't seem to get scrollViewDidEndDecelerating called.
I have a scrollView with 2 Views inside. Now I need it to set a value to a label in the first view when the scrollview is finished scrolling to the second view.
Header File:
#interface ViewController: UIViewController
{
UIScrollView *scrollView;
UIView *view1;
UIView *view2;
}
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
#property (strong, nonatomic) IBOutlet UIView *view1;
#property (strong, nonatomic) IBOutlet UIView *view2;
#property (weak, nonatomic) IBOutlet UILabel *lbl;
Implementation File:
#synthesize scrollView, view1, view2;
-(void)viewDidLoad
{
self.view1=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
self.view2=[[UIView alloc] initWithFrame:CGRectMake(320, 0, 320, 480)];
[self.scrollView addSubView:self.view1];
[self.scrollView addSubView:self.view2];
self.scrollView.bounces=NO;
self.scrollView.contentSize=CGSizeMake(640,460);
[self.scrollView setShowHorizontalScrollIndicator:NO];
[self.scrollView scrollRectToVisible:CGRectMake(0, 0, 320, 416) animated:NO];
}
-(void)scrollViewDidEndDecelerating:(UIView *)scrollView
{
lbl.text=#"0";
}
I don't see anything wrong, it should be working. Can someone help me out? Would appreciate it.

scrollViewDidEndDecelerating is not called if the user is scrolling slowly (i.e. the scroll view does not continue to scroll on touch up). In that case the delegate calls scrollViewDidEndDragging. So to do something when the user has stopped scrolling and the scrollview has stopped you can combine them:
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
endOfScroll()
}
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
endOfScroll()
}
func endOfScroll() {
//The user finished scrolling
}
In Objective-C
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if(!decelerate) [self endOfScroll];
}
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
[self endOfScroll];
}
-(void)endOfScroll{
//Do something
}

Either connect the delegate property of the scrollview to the File's Owner object in Interface Builder or just set the delegate manually in your ViewController's ViewDidLoad.
scrollview.delegate = self

This would do:
Header File:
#interface ViewController: UIViewController <UIScrollViewDelegate> //promise that you'll act as scrollView's delegate
{
UIScrollView *scrollView;
UIView *view1;
UIView *view2;
}
#property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
#property (strong, nonatomic) IBOutlet UIView *view1;
#property (strong, nonatomic) IBOutlet UIView *view2;
#property (weak, nonatomic) IBOutlet UILabel *lbl;
Implementation File:
#synthesize scrollView, view1, view2;
-(void)viewDidLoad
{
self.view1=[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
self.view2=[[UIView alloc] initWithFrame:CGRectMake(320, 0, 320, 480)];
[self.scrollView addSubView:self.view1];
[self.scrollView addSubView:self.view2];
self.scrollView.bounces=NO;
self.scrollView.contentSize=CGSizeMake(640,460);
[self.scrollView setShowHorizontalScrollIndicator:NO];
[self.scrollView scrollRectToVisible:CGRectMake(0, 0, 320, 416) animated:NO];
[self.scrollView setDelegate:self];//Set delegate
}
-(void)scrollViewDidEndDecelerating:(UIView *)scrollView
{
lbl.text=#"0";
}

Swift 5
When scrolling UIScrollView programmatically, the scrollViewDidEndDecelerating is not called , but you can still use the scrollViewDidEndScrollingAnimation delegate function as a substitude for that, however there are some limitations stated in Apple documentation :
The scroll view calls this method at the end of its implementations of the setContentOffset(:animated:) and scrollRectToVisible(:animated:) methods, but only if animations are requested.
Therefore if you are not using default animated:true, but rather animating scrolling with custom UIView.animate animation (for example to change scrolling speed) , the only delegate method that still executes is scrollViewDidScroll

Related

UIButton outside of UIView (xib) frame

I have a custom UIView XIB that gets loaded onto my ViewController and the frame is adjusted to be collapsed before added to subview. The UIButton tied to my XIB is showing when the frame is smaller than the button location. How can I hide and show my UIButton as the frame is expanding/collapsing? My XIB is not using AutoLayout.
ViewController.m
self.greenView = [[[NSBundle mainBundle] loadNibNamed:#"Green" owner:self options:nil] objectAtIndex:0];
[self.navigationController.view addSubview:self.greenView];
GreenView.h
#interface GreenView : UIView
#property (weak, nonatomic) IBOutlet UIView *expandView;
#property (nonatomic, getter = isExpanded) BOOL expand;
#property (weak, nonatomic) IBOutlet UIButton *testButton;
- (IBAction)testButtonTapped:(id)sender;
#end
GreenView.m
#interface GreenView()
#property (nonatomic) UITapGestureRecognizer *tapGesture;
#end
#implementation GreenView
- (void)awakeFromNib {
CGRect frame = self.frame;
frame.size.height = self.expandView.frame.size.height;
frame.origin.y = 200;
self.frame = frame;
self.expand = NO;
[self.expandView addGestureRecognizer:self.tapGesture];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (UITapGestureRecognizer *)tapGesture {
if (!_tapGesture) {
_tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapClicked:)];
}
return _tapGesture;
}
- (void)tapClicked:(UIGestureRecognizer *)recognizer {
CGRect frame = self.frame;
self.expand = !self.expand;
frame.size.height = self.expand ? gvExpandedHeight : gvCollapsedHeight;
[UIView animateWithDuration:0.5 animations:^{
self.frame = frame;
} completion:^(BOOL finished) {
NSLog(#"Frame after animation: %#", NSStringFromCGRect(self.frame));
}];
}
- (IBAction)testButtonTapped:(id)sender {
NSLog(#"Test button tapped");
}
#end
Collapsed:
Expanded:
GreenView.xib:
GrenenView.xib Struts and Springs:
If I understood you just want to clip it, if the button is outside to the view bounds. In -awakeFromNib add:
self.clipsToBounds = YES;
Using this property you are telling the view to cut everything that is not inside its bounds, views caw draw subviews even if they are place outside. Is a little expensive by means of performance, if you use it a lot or during heavy animations.
One way around could be hide it while the view is collapsed.
You change the frame to frame.origin.y = 200;
I think you have to set the UIButton constraint relative to your GreenView in you nib file

Changing UITextView frame

I have ViewController with UITextField(top view) and UITextView(bottom view). I want move UITextView to the top of the view, when user start editing it.
When user start editing from UITextView everything is fine, but when user first want to edit UITextField and then UITextView (without hidding keyboard) its not working. UITextField is hidden, but UITextView don't change his frame.
I tried to use UIKeyboardDidShowNotification but its called only when keyboard pops up.
Code to reproduce problem:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITextViewDelegate>
#property (weak, nonatomic) IBOutlet UITextField *titleTF;
#property (weak, nonatomic) IBOutlet UITextView *bodyTV;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(void)textViewDidBeginEditing:(UITextView *)textView {
self.titleTF.hidden=YES;
CGRect newFrame=CGRectMake(20, 20, textView.frame.size.width, 100);
textView.frame=newFrame;
}
#end
Run app and click on UITextView, app will look like:
http://imageshack.us/photo/my-images/694/32568213.png
For now everything is fine (UITextField is hidden and UITextView is moved and resized).
Start app again. First click on UITextField and then click on UITextView. App look like this:
http://imageshack.us/photo/my-images/843/66433184.png
UITextField is hidden, but UITextView did not change his frame.
Move the view up, when the TextView editing begins,
Move it down when editing ends.
Just put these two methods,
-(void) textViewDidBeginEditing:(UITextView *)textView{
CGRect frame = self.view.frame;
frame.origin.y = -(textView.frame.origin.y + textView.frame.size.height);
[UIView animateWithDuration:0.3f animations:^{
self.view.frame = frame;
}];
}
-(void) textViewDidEndEditing:(UITextView *)textView{
CGRect frame = self.view.frame;
frame.origin.y = 0;
[UIView animateWithDuration:0.3f animations:^{
self.view.frame = frame;
}];
}

Moving UITextField that is located under keyboard

so like im sure every iOS programmer i ran into a problem, when trying to have a page full of UITextFields, it became evident that when the keyboard comes up it covers half of them. So i went to Apple's documentation and read all about it and wrote up the code for it, but it isn't working for me. Every time i run the view it crashes. Thanks in advance for your help.
.h file
#interface NewUserViewController : UIViewController{
}
- (IBAction)signMeUpButtonPressed:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *activeField;
#property (weak, nonatomic) IBOutlet UIScrollView *contentScrollView;
#property (weak, nonatomic) IBOutlet UIButton *backButton;
#property (weak, nonatomic) IBOutlet UILabel *firstNameLabel;
#property (weak, nonatomic) IBOutlet UITextField *firstNameInput;
#property (weak, nonatomic) IBOutlet UILabel *lastNameLabel;
#property (weak, nonatomic) IBOutlet UITextField *lastNameInput;
#property (weak, nonatomic) IBOutlet UILabel *usernameLabel;
#property (weak, nonatomic) IBOutlet UITextField *usernameInput;
#property (weak, nonatomic) IBOutlet UILabel *emailLabel;
#property (weak, nonatomic) IBOutlet UITextField *emailInput;
#property (weak, nonatomic) IBOutlet UILabel *passwordLabel;
#property (weak, nonatomic) IBOutlet UITextField *setPasswordInput;
#property (weak, nonatomic) IBOutlet UILabel *reenterPasswordLabel;
#property (weak, nonatomic) IBOutlet UITextField *checkSetPasswordInput;
#property (weak, nonatomic) IBOutlet UIButton *signMeUpButton;
All are connected to their outlets (except for active field. Im not sure where it belongs or what it should be connected to)
.m file
#implementation NewUserViewController
#synthesize contentScrollView;
#synthesize activeField;
#synthesize firstNameLabel, lastNameLabel, usernameLabel, emailLabel, passwordLabel, reenterPasswordLabel;
#synthesize firstNameInput, lastNameInput, usernameInput, emailInput, setPasswordInput, checkSetPasswordInput;
#synthesize backButton, signMeUpButton;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
}
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
contentScrollView.contentInset = contentInsets;
contentScrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your application might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height);
[contentScrollView setContentOffset:scrollPoint animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
contentScrollView.contentInset = contentInsets;
contentScrollView.scrollIndicatorInsets = contentInsets;
}
- (IBAction)signMeUpButtonPressed:(id)sender {
}
Try this:
- (void)keyboardWasShown:(NSNotification *)notification {
NSDictionary* userInfo = [notification userInfo];
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
//offset is global
offset = contentScrollView.contentOffset;
CGRect viewFrame = contentScrollView.frame;
CGRect keyboardFrame = [self convertRect:keyboardEndFrame toView:nil];
viewFrame.size.height -= keyboardFrame.size.height;
contentScrollView.frame = viewFrame;
UITextField *current = (UITextField *)[self findFirstResponder];
CGRect textFieldRect = current.frame;
[contentScrollView scrollRectToVisible:textFieldRect animated:YES];
}
- (UIView *)findFirstResponder {
for (UIView *subView in scrollView.subviews) {
if ([subView isFirstResponder]){
return subView;
}
}
return nil;
}
- (void) keyboardWillBeHidden:(NSNotification *)notification {
//scrollViewFrame is global the first frame of you scrollview
contentScrollView.frame = scrollViewFrame;
contentScrollView.contentOffset =offset;
}
this is not a complete code this is just a little logic of performing what you want to do.

UIView is not showing up in UIScrollView

I am currently dynamically adding a UIImage to my UIScrollView object and everything is working as intended. I need to add extra functionality now (a UIActivityIndicator in the center of the image when it is loading from the internet, and a label underneath) so I thought why not create a custom View which has all of these laid out as I need them to be, and then just load it into the scrollView. I have encountered a problem though, when I add it to the scrollView, nothing shows up. Here is what I have:
NewsViewController.m:
imageScrollView.contentSize = CGSizeMake(320*numberOfPages, 303);
pageControl.numberOfPages = numberOfPages;
dispatch_queue_t imageDownload = dispatch_queue_create("imageDownload", NULL);
__block NSData *temp;
CustomImageView *customImageView = [[CustomImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 303)];
[imageScrollView addSubview:customImageView];
[[customImageView activityIndicator] startAnimating];
dispatch_async(imageDownload, ^{
temp = [[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.wlfarm.org/wp-content/uploads/2012/05/farm.jpg"]]retain];
dispatch_async(dispatch_get_main_queue(), ^{
customImageView.imageView.image = [[UIImage alloc] initWithData:temp];
[[customImageView activityIndicator] stopAnimating];
[customImageView setNeedsDisplay];
customImageView.caption.text = #"HAHAHAHAHHAHA";
[imageScrollView setNeedsDisplay];
[temp release];
});
});
dispatch_release(imageDownload);
CustomImageView.h:
#import <UIKit/UIKit.h>
#interface CustomImageView : UIView
{
IBOutlet UIImageView *imageView;
IBOutlet UILabel *caption;
IBOutlet UIActivityIndicatorView *activityIndicator;
}
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
#property (nonatomic, retain) IBOutlet UILabel *caption;
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView *activityIndicator;
#end
CustomImageView.m
#import "CustomImageView.h"
#interface CustomImageView ()
#end
#implementation CustomImageView
#synthesize caption, imageView, activityIndicator;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
I am including a screenshot of my XIB file, and the program running on the simulator. The first picture shows nothing in the scrollView(the attempt made by using my custom class), and the second page of the scroll view is the attempt made by adding a UIImageView to the UIScrollView(which worked). Can anyone point out what I am doing wrong? Am I not allowed to load a custom view into a UIScrollView? Thanks for your help!
IB Screenshot - http://i.stack.imgur.com/gz9UL.png
iOS Simulator No Image with CustomView Screenshot - http://i.stack.imgur.com/zhswq.png
iOS Simulator Image with UIImageView Screenshot - http://i.stack.imgur.com/97vmU.png
It looks as though CustomImageView is a subclass on UIViewController, not UIImageView or UIView. You can't add a UIViewController as a subview like that. change it to subclass UIView and it should work.
To load a UIView from a .nib, you need to declare your IBOutlet properties as you would for a UIViewController. Define the correct custom class in IB and connect everything up, including the base view. Then override the following method inside your custom view class.
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code.
//
[[NSBundle mainBundle] loadNibNamed:#"<NIB NAME HERE>" owner:self options:nil];
[self addSubview:self.view];
}
return self;
}
It seems you have cut and pasted methods from a UIViewController subclass into you UIView subclass. Start by deleting all the methods you've pasted in between #synthesize and #end . A UIView subclass requires different methods to to load from a .nib, so you need to override the method shown above instead and use the line of code
[[NSBundle mainBundle] loadNibNamed:#"<NIB NAME HERE>" owner:self options:nil];
to load the nib.
Further to your comment about connecting the base view, here is what I mean:
After creating your custom class and nib file, open the nib and highlight "Files Owner" on the left, then on the top right hand side, select the icon 3rd from the left, looks like an ID card or something. In the "Class" box, add the name of your custom class.
In your customClass, add an IBOutlet UIView property called baseView, and add a UIView that covers the view in IB at the root level, connect these two. Then add everything else on top of that
you code would now look something like this:
CustomImageView.h
#import <UIKit/UIKit.h>
#interface CustomImageView : UIView
{
IBOutlet UIView *baseView
IBOutlet UIImageView *imageView;
IBOutlet UILabel *caption;
IBOutlet UIActivityIndicatorView *activityIndicator;
}
#property (nonatomic, retain) IBOutlet UIView *baseView;
#property (nonatomic, retain) IBOutlet UIImageView *imageView;
#property (nonatomic, retain) IBOutlet UILabel *caption;
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView *activityIndicator;
#end
CustomImageView.m
#import "CustomImageView.h"
#interface CustomImageView ()
#end
#implementation CustomImageView
#synthesize baseView, caption, imageView, activityIndicator;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code.
//
[[NSBundle mainBundle] loadNibNamed:#"<NIB NAME HERE>" owner:self options:nil];
[self addSubview:self.baseView];
}
return self;
}
#end
Provided you connect it all up in IB it should work fine, just remember to add the baseView
As mentioned earlier initWithNibName belongs to controllers.
As I think, you're going the wrong way.
you have a ViewController and want to add a customView, to load dynamically a image from URLData.
You have 2 Options:
Option 1: Do everything in IB:
In Interfacebuilder edit/(or add a new one) the ViewController's XIB File and add the views that you like. The file's owner is a UIViewController Class/Subclass. Do everything like you did before, except doing it in the view controller. In your App delegate initWithNibName your ViewController like so
self.viewController = [[testViewController alloc] initWithNibName:#"testViewController" bundle:nil];
If you want to, initialize your own view controller, which you like to push and push it in the stack.
What you're doing wrong: You are initializing a customImageView with a Frame, but the nib doesn't get loaded automatically. The Properties are there, but the nib isn't.
If you really want a stable thing choose
Option 2: Do everything programatically (It is easier, more understanding and lightweight):
From your implementation we do the following:
NewsViewController.m
Do like you did before!!!
CustomImageView.h:
#import <UIKit/UIKit.h>
#interface CustomImageView : UIView
{
UIImageView *imageView;
UILabel *caption;
UIActivityIndicatorView *activityIndicator;
}
#property (nonatomic, retain) UIImageView *imageView;
#property (nonatomic, retain) UILabel *caption;
#property (nonatomic, retain) UIActivityIndicatorView *activityIndicator;
#end
CustomImageView.m:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
caption = [[UILabel alloc] initWithFrame:CGRectMake(0, 250, 320, 50)];
[caption setBackgroundColor:[UIColor greenColor]];
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 250)];
[imageView setBackgroundColor:[UIColor blueColor]];
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
self.activityIndicator.frame = CGRectMake(320/2-25, 460/2-25, 50, 50);
[self.activityIndicator startAnimating];
[self addSubview:self.caption];
[self addSubview:self.imageView];
[self addSubview:self.activityIndicator];
}
return self;
}
Then do everything you did before.
That would do a better job

iOS - adding/removing a subview programmatically

Ok I want to add a UIImageView as a subview and then remove it after a couple of seconds in the way a splash screen works. I found three different approaches to do it but I can not understand which one is the best approach according to Objective-C and Apple.
Below are the three different approaches:
1)
In my MyAppDelegate.h
#interface MyAppDelegate : NSObject <UIApplicationDelegate> {
MyViewController *myViewController;
UIImageView *myImageView;
}
#property (nonatomic, retain) IBOutlet MyViewController *myViewController;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
and in MyAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
myImageView =[[UIImageView alloc] initWithFrame:CGRectMake(0.0,0.0,self.window.frame.size.width,self.window.frame.size.height)];
myImageView.image=[UIImage imageNamed:#"Yoga.png"];
[self.window addSubview:myImageView ];
[self.window bringSubviewToFront:myImageView];
[self performSelector:#selector(removeImage) withObject:nil afterDelay:2.5];
return YES;
}
-(void) removeImage
{
[myImageView removeFromSuperview];
[myImageView release];
[self.window addSubview:myViewController.view];
[self.window makeKeyAndVisible];
}
2) in the second approach:
In my MyAppDelegate.h
#interface MyAppDelegate : NSObject <UIApplicationDelegate> {
MyViewController *myViewController;
UIImageView *myImageView;
}
#property (nonatomic, retain) IBOutlet UIImageView *myImageView;
#property (nonatomic, retain) IBOutlet MyViewController *myViewController;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
and in MyAppDelegate.m
#synthesize myImageView;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
myImageView =[[UIImageView alloc] initWithFrame:CGRectMake(0.0,0.0,self.window.frame.size.width,self.window.frame.size.height)];
myImageView.image=[UIImage imageNamed:#"Yoga.png"];
[self.window addSubview:myImageView ];
[self.window bringSubviewToFront:myImageView];
[self performSelector:#selector(removeImage) withObject:nil afterDelay:2.5];
return YES;
}
-(void) removeImage
{
[myImageView removeFromSuperview];
[myImageView release];
[self.window addSubview:myViewController.view];
[self.window makeKeyAndVisible];
}
- (void)dealloc
{
[myViewController release];
[myImageView release];
}
3) in the third approach:
In my MyAppDelegate.h
#interface MyAppDelegate : NSObject <UIApplicationDelegate> {
MyViewController *myViewController;
}
#property (nonatomic, retain) IBOutlet MyViewController *myViewController;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
and in MyAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIImageView *myImageView =[[UIImageView alloc] initWithFrame:CGRectMake(0.0,0.0,self.window.frame.size.width,self.window.frame.size.height)];
myImageView.image=[UIImage imageNamed:#"Yoga.png"];
myImageView.tag=22;
[self.window addSubview:myImageView ];
[myImageView release];
[self.window bringSubviewToFront:myImageView];
[self performSelector:#selector(removeImage) withObject:nil afterDelay:2.5];
return YES;
}
-(void) removeImage
{
for (UIView *subview in [self.view subviews]) {
if (subview.tag == 22){
[subview removeFromSuperview];
}
}
[self.window addSubview:myViewController.view];
[self.window makeKeyAndVisible];
}
- (void)dealloc
{
[myViewController release];
}
So to sum up.. The first approach does not use a property for the UIImage only a variable, the second one uses a property and the third one just creates the UIImage and adds it as a subview and then removes it based on its tag..
Which is the right approach to follow..I believe that all three options sound right.. But is there any certain way I should follow. Is any of these options better in terms of memory and performance?
Thanks in advance,
Andreas
You could use an animation attached to the view's layer. Code below fades the view out - but there are many other ways to remove it. (you need to attach the QuartzCore framework)
myImageView.layer.opacity = 0.0;
// this is the state the view will be in after the animation (e.g. invisible)
CABasicAnimation *theFade;
theFade = [CABasicAnimation animationwithKeyPath:#"opacity"];
theFade.duration = 10.0;
theFade.fromValue = [NSNumber numberWithFloat:1.0]; // i.e. visible
theFade.toValue = [NSNumber numberWithFloat:0.0]; // i.e. invisible
[myImageView.layer addAnimation:theFade forKey:#"animateOpacity"];
If you are not going to use the image again, there is no need to keep a pointer to it. Further, if you use IBOutlet, you need to add the view in IB as well. In this specific example I would say option 3 makes the most sence, especially considering that with this choice you can began with a standard "view based application" template and just add the bits about the image view and leave the rest alone. One last observation of choice 3 though; the 2 messages to window;
[self.window addSubview:myViewController.view];
[self.window makeKeyAndVisible];
Appear to be outside the scope of any method. This is likely just a copy and paste error, but make note that they should located within "didFinishLaunchingWithOptions:"