how to update a view in viewDidAppear - objective-c

I try to create a pseudo-animation, when a view will appear. Here is my code:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
_image1.hidden = NO;
sleep(1);
_label1.hidden = YES;
sleep(1);
_image2.hidden = NO;
sleep(1);
_label2.hidden = YES;
sleep(1);
}
But the view is not updated before each sleep(). What does I have to add, that the view will be updated after I show or hide a image or label?

Try this:
[_image1 performSelector:#selector(setHidden:) withObject:[NSNumber numberWithBool:true] afterDelay:1];
[_label1 performSelector:#selector(setHidden:) withObject:[NSNumber numberWithBool:false] afterDelay:2];
[_image2 performSelector:#selector(setHidden:) withObject:[NSNumber numberWithBool:true] afterDelay:3];
[_label2 performSelector:#selector(setHidden:) withObject:[NSNumber numberWithBool:false] afterDelay:4];

You can't use sleep because it stops your current thread and will prevent your app from updating the display.
I recommend to use...
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5]; // you can also set this to 0.0
[UIView setAnimationDelay:1.0]; // the delay
// your changes which should be animated, example:
_image1.alpha = 0.0;
[UIView commitAnimations];
simple and extendable.

Related

UIView animation not working when used with DCRoundSwitch

I have done following code for animation inside a selector method of custom UISwitch DCRoundSwitch.
if ([[[App.remindersArray objectAtIndex:0] objectAtIndex:3]isEqualToString:#"YES"]){
[firstReminderOnOffButton setSelected:YES];
[swtchDailyReminder setOn:YES];
imgviewDailyReminder.image=[UIImage imageNamed:#"nDailyReminder_On_1.png"];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.35];
[UIView setAnimationDidStopSelector:#selector(animateFadingIn)];
[UIView setAnimationDelegate:self];
imgviewDailyReminderAnimation.alpha = 1.0;
[UIView commitAnimations];
}
else
{
[firstReminderOnOffButton setSelected:NO];
[swtchDailyReminder setOn:NO];
imgviewDailyReminder.image=[UIImage imageNamed:#"xDailyReminder_OFF.png"];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.35];
[UIView setAnimationDidStopSelector:#selector(animateFadingIn)];
[UIView setAnimationDelegate:self];
imgviewDailyReminderAnimation.alpha = 0.0;
[UIView commitAnimations];
}
The problem is animation is working properly when above code is called from normal UISwitch,but not working when called from DCRoundSwitch.
Also tried to resolve by using UIView block animation....but still facing the problem.
Please guide me.
The issue is in DCRoundSwitch's animation block. No CATransaction is created in the completion block of setOn:animated:ignoreControlEvents: resulting in [UIView animateWithDuration...] methods not working properly when called in response to the switch's value being changed.
To solve the problem, just change:
if (previousOn != on && !ignoreControlEvents)
[self sendActionsForControlEvents:UIControlEventValueChanged];
To:
if (previousOn != on && !ignoreControlEvents)
{
[CATransaction begin];
[CATransaction setDisableActions:NO];
[self sendActionsForControlEvents:UIControlEventValueChanged];
[CATransaction commit];
}
That should do it
i have used this below code. which works correctly.
Please follow up this thread
https://github.com/domesticcatsoftware/DCRoundSwitch/issues/12
U can just go to the Class which is using this DCRoundSwitch , on that class's dealloc method put this line.
- (void)dealloc
{
[self.MyDCRoundSwitch removeTarget:nil
action:NULL
forControlEvents:UIControlEventAllEvents];
[super dealloc];
}

Thread 1:EXC_BAD_ACCESS while changing ViewControllers

I needed to chance my ViewControllers, so I used this function:
(void)pushViewFromRight:(UIViewController*)coming over:(UIViewController*)going {
CGRect frameComing = coming.view.frame;
CGRect frameGoing = going.view.frame;
frameComing.origin.x = 0;
frameComing.origin.y = -460;
coming.view.frame = frameComing;
if ([coming.view superview] == nil)
[SlideContainer addSubview:coming.view];
[UIView beginAnimations:#"frame" context:nil];
[UIView setAnimationDuration:1];
[coming viewWillAppear:YES];
[going viewWillAppear:YES];
frameComing.origin.y = 0;
coming.view.frame = frameComing;
going.view.frame = frameGoing;
[going viewDidDisappear:YES];
[coming viewDidAppear:YES];
[UIView commitAnimations];
}
On the Second ViewController I created a button to go back.
But when I want to go back, (even if there are no actions after pressing the button), it crashes with EXC_BAD_ACCESS.
Why does this happen?

Checking if the UIPickerView is shown or hidden? The *if* conditions?

I have a little problem with my UIPickerView animation.
I did set up the animation so when I click a button the UIPickerView will slide up and after another click it will slide down. But I hit the problem on if. I tried to set up a new settings bool and set it's value after each animation, so the if was just checking for the bool. I'm not sure if I did explained it well, but maybe you get the idea from the code.
But unfortunately it's not working... Any ideas?
- (void)viewDidLoad
{
[super viewDidLoad];
settings = [NSUserDefaults standardUserDefaults];
[settings setBool:NO forKey:#"pickerShown"];
[settings synchronize];
}
- (IBAction)showPicker:(id)sender {
CGRect rect = countryPicker.frame;
CGPoint origin = CGPointMake(0, 510); // Some off-screen y-offset here.
rect.origin = origin;
countryPicker.frame = rect;
if ([settings boolForKey:#"pickerShown"] == YES) {
// Perform transform to slide it off the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
countryPicker.transform = CGAffineTransformMakeTranslation(0, -0); // Offset.
[UIView commitAnimations];
[settings setBool:NO forKey:#"pickerShown"];
[settings synchronize];
} else if ([settings boolForKey:#"pickerShown"] == NO) {
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
countryPicker.transform = CGAffineTransformMakeTranslation(0, -266); // Offset.
[UIView commitAnimations];
[settings setBool:YES forKey:#"pickerShown"];
[settings synchronize];
}
}
EDIT:
Just found the solution...
If anyone's interested - here it is:
The h. file:
.
.
.
{
BOOL pickerShown;
}
.
.
.
The .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect rect = countryPicker.frame;
CGPoint origin = CGPointMake(0, 510); // Some off-screen y-offset here.
rect.origin = origin;
countryPicker.frame = rect;
pickerShown = NO;
}
- (IBAction)showPicker:(id)sender {
if (pickerShown == NO) {
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
//[UIView setAnimationDidStopSelector:#selector(hidePicker)];
countryPicker.transform = CGAffineTransformMakeTranslation(0, 0); // Offset.
[UIView commitAnimations];
[self performSelector:#selector(hidePicker) withObject:nil afterDelay:1];
} else if (pickerShown == YES) {
//countryPicker.hidden = NO;
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
countryPicker.transform = CGAffineTransformMakeTranslation(0, -266); // Offset.
[UIView commitAnimations];
countryPicker.hidden = NO;
}
}
If a view is visible on screen, it's window property will be non-nil.
Just found the solution... If anyone's interested - here it is:
The h. file:
.
.
.
{
BOOL pickerShown;
}
.
.
.
The .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect rect = countryPicker.frame;
CGPoint origin = CGPointMake(0, 510); // Some off-screen y-offset here.
rect.origin = origin;
countryPicker.frame = rect;
pickerShown = NO;
}
- (IBAction)showPicker:(id)sender {
if (pickerShown == NO) {
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
//[UIView setAnimationDidStopSelector:#selector(hidePicker)];
countryPicker.transform = CGAffineTransformMakeTranslation(0, 0); // Offset.
[UIView commitAnimations];
[self performSelector:#selector(hidePicker) withObject:nil afterDelay:1];
} else if (pickerShown == YES) {
//countryPicker.hidden = NO;
// Perform transform to slide it onto the screen.
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
countryPicker.transform = CGAffineTransformMakeTranslation(0, -266); // Offset.
[UIView commitAnimations];
countryPicker.hidden = NO;
}
}
You can check it with:
self.countryPicker.superview
If picker is hidden then superview will be nil. Otherwise it will be containing view.
If all you want is the basic effect of displaying the picker view, then removing it again there is an easier way.
pseudocode:
//do any picker initialization here
if(!pickerIsShowing)
[self.view addSubview:yourPickerView];
else
[self.yourPickerView removeFromSuperView];

Auto scroll functionality in iPhone SDK

I had added auto scroll functionality to my application by going through sample code.
In this code I'm getting scroll from top to bottom and bottom to top. But I don't want to scroll from top to bottom . I always wants to scroll from bottom to top only. If I'm removing the topToBottom code and making changes to the remaining code according to that it is not working. Can any one help me.
-(void)viewdidLoad
{
infoScrollView = [[UIScrollView alloc]init];
infoScrollView.frame = CGRectMake(0,0,330,270);
infoScrollView.contentSize = CGSizeMake(100,1000);
[myInfoView addSubview:infoScrollView];
scrollingToTop=NO;
UIImageView *infoImgView = [[UIImageView alloc]initWithFrame:CGRectMake(70,0,200,1000)];
infoImgView.image = [UIImage imageNamed:#"lepke-tar2.png"];
[infoScrollView addSubview:infoImgView];
infoScrollView.delegate = self;
if (infoScrollView.contentSize.height>infoScrollView.frame.size.height)
{
[infoScrollView scrollRectToVisible:CGRectMake(0, infoScrollView.contentSize.height-infoScrollView.frame.size.height, infoScrollView.frame.size.width, infoScrollView.frame.size.height) animated:NO];
}
[self performSelector:#selector(scrollToTop) withObject:nil afterDelay:0.5];
[myInfoView addSubview:infoScrollView];
UIButton* infocancelBttn = [[UIButton alloc ]initWithFrame:CGRectMake(295,-8,45,45)];
[infocancelBttn setImage:[UIImage imageNamed:#"cancel_icon.png"] forState:UIControlStateNormal];
[infocancelBttn addTarget:self action:#selector(infoViewCloseAction) forControlEvents:UIControlEventTouchUpInside];
[myInfoView addSubview:infocancelBttn];
[infocancelBttn release];
}
-(void)viewDidAppear:(BOOL)animated
{
[infoScrollView scrollRectToVisible:CGRectMake(0, 0, infoScrollView.frame.size.width, infoScrollView.frame.size.height+200) animated:YES];
}
- (void) scrollToTop
{
scrollingToTop=YES;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:10.0];
//[self.scrollView scrollRectToVisible:CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height) animated:YES];
[infoScrollView setContentOffset:CGPointMake(0,-300)];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(scroll)];
[UIView commitAnimations];
}
-(void) scroll
{
if (scrollingToTop==YES)
{
[self performSelector:#selector(scrollToBottom) withObject:nil afterDelay:1.0];
}
else
{
[self performSelector:#selector(scrollToTop) withObject:nil afterDelay:1.0];
}
}
- (void)scrollToBottom
{
scrollingToTop=NO;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:10.0];
[infoScrollView setContentOffset:CGPointMake(0,infoScrollView.contentSize.height-infoScrollView.frame.size.height)animated:NO];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(scroll)];
[UIView commitAnimations];
}
I think your if-statement is wrong:
-(void) scroll
{
if (scrollingToTop==YES)
{
[self performSelector:#selector(scrollToBottom) withObject:nil afterDelay:1.0];
}
else...
if you delete your scrollToBottom-method your code fails.
you should change this to
[self performSelector:#selector(scrollToTop) withObject:nil afterDelay:1.0];
because you are asking if scrollingToTop is true

Handling Device orientation problem for swapped views

i'm doing an ipad application, in which i have say two views
mainview and aboutus view
on startup i put the mainview in the rootcontroller's view (the one that is added to the window) alone.
and there's a button on mainview, that, when pressed, will remove the mainview from superview and put the aboutusview instead. aboutus has a similar button that gets us back to mainview.
Now the problem lies in the rotation (orientation).
when i detect an orientation change, i update the displayed view. works fine. (for mainview and aboutusview)
But if i rotate once any view, and then then try to see the second view. it seems that the second view is not autosizing.
CODE in rootViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
_currentOrientation=UIDeviceOrientationPortrait;
[self.view addSubview:_mainView];
[_splashView removeFromSuperview];
}
-(void)viewDidAppear:(BOOL)animated
{
_currentView = _mainView;
}
-(void)toggleMainPage
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:[self view] cache:YES];
[_infoView removeFromSuperview];
[self.view addSubview:_mainView];
_currentView=_mainView;
[self transformViewAccordingToOrientation:_currentOrientation];
[UIView commitAnimations];
}
-(void)toggleAboutPage
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self view] cache:YES];
[_mainView removeFromSuperview];
[self.view addSubview:_infoView];
_currentView=_infoView;
[self transformViewAccordingToOrientation:_currentOrientation];
[UIView commitAnimations];
}
-(void) transformViewAccordingToOrientation:(UIDeviceOrientation)toInterfaceOrientation
{
if(toInterfaceOrientation == UIDeviceOrientationPortrait)
{
[_mainBtnCustom setBackgroundImage:[UIImage imageNamed:#"main.png"] forState:UIControlStateNormal];
_infoImage.image = [UIImage imageNamed:#"about.png"];
}else
{
[_mainBtnCustom setBackgroundImage:[UIImage imageNamed:#"mainr.png"] forState:UIControlStateNormal];
_infoImage.image = [UIImage imageNamed:#"aboutr.png"];
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self transformViewAccordingToOrientation:toInterfaceOrientation];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
_currentOrientation = [UIDevice currentDevice].orientation;
[self transformViewAccordingToOrientation:_currentOrientation];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (_currentOrientation !=interfaceOrientation);
}
what am i doing wrong?