I've scrollview with page control and I want to make the subview of my scrollview fadeIn/fadeOut when I scroll to or from the next page. I found that I can use contentOffset to make this effect but I couldn't make it.
In fact, I'm newbie and I wish If there is any tutorial that can help. thank you.
Assuming you hold an array of your view controllers in self.viewControllers indexed according to the UIPageControl:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat diffFromCenter = ABS(scrollView.contentOffset.x - (self.pageControl.currentPage)*self.view.frame.size.width);
CGFloat currentPageAlpha = 1.0 - diffFromCenter/self.view.frame.size.width;
CGFloat sidePagesAlpha = diffFromCenter/self.view.frame.size.width;
//NSLog(#"%f",currentPageAlpha);
[[[self.viewControllers objectAtIndex:self.pageControl.currentPage] view] setAlpha:currentPageAlpha];
if (self.pageControl.currentPage > 0)
[[[self.viewControllers objectAtIndex:self.pageControl.currentPage-1] view] setAlpha:sidePagesAlpha];
if (self.pageControl.currentPage < [self.viewControllers count]-1)
[[[self.viewControllers objectAtIndex:self.pageControl.currentPage+1] view] setAlpha:sidePagesAlpha];
}
You might check out this tutorial on view animation:
Uiview-tutorial-for-ios-how-to-use-uiview-animation
To achieve the effect you are looking for you can use something like this:
ScrollView delegate method to detect scrolling (if your only paging)
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
UIView* subView = [scrollView.subviews lastObject]; //Or however you access your subview
[UIView animateWithDuration:1.0f animations:^{
subView.alpha = 0.0f;
} completion:^(BOOL finished){
[UIView animateWithDuration:1.0f animations:^{
subView.alpha = 1.0f;
}];
}];
}
This will cause your subview to smoothly fade out and in within the span of 2.0 seconds. You should a bit of reading about this animation blocks though as they can be a little tricky. For instance I had nest the second animation block after the first had complete because the actual code within them is handled immediately and the animation simply takes place on the View side of things.
Hope this helps!
You can fade it to zero, change the contentOffset without animation, and fade it back to alpha with 1.0:
- (IBAction)didChangePageView:(id)sender
{
[UIView animateWithDuration:0.25
animations:^{
self.scrollView.alpha = 0.0;
}
completion:^(BOOL finished) {
[self.scrollView setContentOffset:CGPointMake(0, self.scrollView.frame.size.height * self.pageViewControl.currentPage) animated:NO];
[UIView animateWithDuration:0.25 animations:^{
self.scrollView.alpha = 1.0;
}];
}];
}
With Swift 2.0, assuming you hold an array of your subViews in myViewsArray:
func scrollViewDidScroll(scrollView: UIScrollView) {
//Fade in/out effect while scrolling
for (index,subView) in myViewsArray.enumerate() {
label.alpha = 1 - abs(abs(scrollView.contentOffset.x) - subView.frame.width * CGFloat(index)) / subView.frame.width
}
}
Related
I am using ShakingAlertView in my app.
https://github.com/lukestringer90/ShakingAlertView
It works perfectly in IOS 6. But after i updating to IOS 7 it didnt animate and the block function for incorrect handing not being called.
Given below is the code for the initialization of shaking alert view.
currentPass = [[ShakingAlertView alloc]initWithAlertTitle:#"Enter Current Password" checkForPassword:self.pass
usingHashingTechnique:HashTechniqueMD5
onCorrectPassword:^{
isCurrentPassConfirmed = YES;
[self._accountSource willScrollToTop];
self.password.text = #"";
[self.password becomeFirstResponder];
} onDismissalWithoutPassword:^{
//NSLog(#"hi");
[self showFailedPasswordAlert];
}];
currentPass.alertViewStyle = UIAlertViewStyleSecureTextInput;
[currentPass show];
Below is the method to animate for shake effect.This is invoked correctly but there is no effect.
- (void)animateIncorrectPassword {
// Clear the password field
_passwordField.text = nil;
// Animate the alert to show that the entered string was wrong
// "Shakes" similar to OS X login screen
CGAffineTransform moveRight = CGAffineTransformTranslate(CGAffineTransformIdentity, 20, 0);
CGAffineTransform moveLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -20, 0);
CGAffineTransform resetTransform = CGAffineTransformTranslate(CGAffineTransformIdentity, 0, 0);
[UIView animateWithDuration:0.1 animations:^{
// Translate left
self.transform = moveLeft;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
// Translate right
self.transform = moveRight;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
// Translate left
self.transform = moveLeft;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
// Translate to origin
self.transform = resetTransform;
}];
}];
}];
}];
}
Please help me.
iOS7 does not allow you to customize the UIAlertview.
Better create the custom view subclass of UIView which is draw the
view programmatically using - (void)drawRect:(CGRect)rect method.
And create one more container class(inherited from NSObject) which
is used to create and bind your title/password and OK buttons
with your custom delegate property into your customized alert
view.So that we can implement our custom delegate method as like
clickedButtonAtIndex method.
Upto my knowledge there is no changes in block/animation in iOS7.
Or refer this link https://github.com/wimagguc/ios-custom-alertview
The layout of UIAlertView changed drastically is iOS 7, making it almost impossible to customise and alter. You're going to have to come up with a new solution.
I'm trying to apply a fade to an UIView I created programmatically on the top of another.
[UIView animateWithDuration:0.5 animations:^(void) {
[self.view setAlpha:0];
}
completion:^(BOOL finished){
[self.view removeFromSuperview];
}];
The finished event is called properly after exactly 0.5 seconds, but I don't see any fade (I should see the UIView on the bottom).
If instead of using the alpha, I move away the UIView it works (I see the bottom UIView while the top UIView slides away), so it seems to be a problem related to alpha, but I can't figure out what's wrong!
[UIView animateWithDuration:0.5 animations:^(void) {
CGRect o = self.view.frame;
o.origin.x = 320;
self.view.frame = o;
}
completion:^(BOOL finished){
[self.view removeFromSuperview];
}];
I used alpha animations previously and they works in this way usually...
Try setting opaque to NO explicitly. I had the same problem and setting that solved my problem. Apparently, opaque views just don't seem to play well with alpha.
Credit goes to Hampus Nilsson's comment though.
I experience same issue in my case its because of thread
So i end up with write animation block in main thread.
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
View.alpha = 0.0f;
} completion:^(BOOL finished) {
}];
});
[UIView animateWithDuration:0.6 delay:0 options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[self.view setAlpha:0];
}
completion:^(BOOL finished) {
[self.view removeFromSuperview];
}];
This will work right, and your fading will be nicer, because of options:UIViewAnimationOptionCurveEaseInOut.
I ran into the exact problem. In my case, I wanted the view to be hidden at first, so I set hidden to true. I thought changing the alpha value changes hidden property automatically, but that wasn't the case.
So, if you want the view to be hidden at first, set its alpha to 0.
I had exactly the same problem, and none of the suggestions worked for me. I overcame the problem by using the layer opacity instead.
This is the code for showing the layer (using Xamarin, but you'll get the idea):
//Enter the view fading
zoomView.Layer.Opacity = 0;
UIApplication.SharedApplication.KeyWindow.RootViewController.View.Add(zoomView);
UIView.AnimateNotify(
0.15, // duration
() => { zoomView.Layer.Opacity = 1.0f },
(finished) => { }
);
And this is for fading out the same zoomView
UIView.AnimateNotify(
0.15, // duration
() => { zoomView.Layer.Opacity = 0; },
(finished) =>
{
if (finished)
{
zoomView.RemoveFromSuperview();
}
}
);
One more piece of the puzzle. When you're animating constraints, you can set the new constraint constants outside of an animation block and then call layoutIfNeeded inside the animation.
With view alphas, these need to be set directly inside the animation block.
Change this:
//setup position changes
myConstraint.constant = 10
myOtherConstraint.constant = 10
//whoops, alpha animates immediately
view.alpha = 0.5
UIView.animate(withDuration: 0.25) {
//views positions are animating, but alpha is not
self.view.layoutIfNeeded()
}
to
//setup position changes
myConstraint.constant = 10
myOtherConstraint.constant = 10
UIView.animate(withDuration: 0.25) {
view.alpha = 0.5
self.view.layoutIfNeeded()
}
i want to hide navigationbar and tabbar on touch and move on uitableview, blow code:
_headView from viewForHeaderInSection it's no problem.
but sometimes after block Executed, _headView is visible
if(_headView)
_headView.hidden = YES; //
[UIView animateWithDuration:0.5 animations:^{
scrollView.frame = rect;
_vc.navigationController.navigationBar.top -= navigationBarHeight;
tabView.top = SCREEN_HEIGHT;
} completion:^(BOOL finished) {
}];
if i move hide code to completion block , it's run OK, but hide after 0.5 sec, it's slowly .
[UIView animateWithDuration:0.5 animations:^{
scrollView.frame = rect;
_vc.navigationController.navigationBar.top -= navigationBarHeight;
tabView.top = SCREEN_HEIGHT;
} completion:^(BOOL finished) {
if(_headView)
_headView.hidden = YES; //Delay after 0.5s.
}];
please help me , thanks.
We have a delegate method for the setting height of section for UITableView
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
just return 0 for this, for hiding header.
Sorry for the poor title, I am trying to think of a easy way to explain this.
I have a UIView in the center of the screen which contains a progress indicator and background image.
What I want it to do is get bigger to a certain point and then shrink a tiny bit. So it "boings" in.
I had a play with normal UIView animations etc and have it coming in. However I thinking to get this to work well I need to use the views layer. The main issue at the moment is the indicator does not size.
Has anyone done a boing effect on a view?
Something like this?
- (void)boingView:(UIView *)theView {
[UIView animateWithDuration:0.1 animations:^(void) {
theView.transform = CGAffineTransformMakeScale(1.3, 1.3);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^(void) {
theView.transform = CGAffineTransformMakeScale(0.8, 0.8);
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^(void) {
theView.transform = CGAffineTransformMakeScale(1.0, 1.0);
} completion:nil];
}];
}];
}
I need to create a expandable and collapsible UIView of some sort and am not able to pay for a third party control.
This is basically how I would like it to behave:
At the top there should be a UIButton (or similar) that allows the user to toggle between expanded and collapsed.
When expanded I want to be able to place other UIView (e.g. calendar)and when collapsed the surrounding controls should move up.
Does anyone have any ideas how to implement this simply - noob here :(
Subclass a ViewController and have two methods that your button can fire like 'collapse' and 'expand', this might get you started: You can assign new selectors to UIButtons dynamically:
[button addTarget:self action:#selector(eventMethod:)
forControlEvents:UIControlEventTouchUpInside];
Code:
#define COLAPSED_HEIGHT 30
-(void)expand
{
CGRect s= [self getScrerenBoundsForCurrentOriantation];
CGRect f = self.view.frame;
f.origin.y =s.size.height-self.view.frame.size.height;
[UIView beginAnimations:#"expand" context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationFinished:finished:context:)];
self.view.frame=f;
//CHANGE YOUR EXPAND/COLLAPSE BUTTON HERE
[UIView commitAnimations];
self.thumbScrollerIsExpanded=YES;
}
-(void)collapseView
{
//re-factored so that this method can be called in ViewdidLoad
CGRect s= [self getScrerenBoundsForCurrentOriantation];
CGRect f = self.view.frame;
f.origin.y =(s.size.height-COLAPSED_HEIGHT);
self.view.frame = f;
self.thumbScrollerIsExpanded=NO; //thumbScrollerIsExpanded is a BOOL property
}
- (void)collapse
{
[UIView beginAnimations:#"collapse" context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationFinished:finished:context:)];
[self collapseView];
//CHANGE YOUR EXPAND/COLLAPSE BUTTON HERE
[UIView commitAnimations];
}
-(CGRect)getScrerenBoundsForCurrentOriantation
{
return [self getScrerenBoundsForOriantation:[[UIDevice currentDevice] orientation]];
}
-(CGRect)getScrerenBoundsForOriantation:(UIInterfaceOrientation)_orientation
{
UIScreen *screen = [UIScreen mainScreen];
CGRect fullScreenRect = screen.bounds; // always implicitly in Portrait orientation.
if (UIInterfaceOrientationIsLandscape(_orientation))
{
CGRect temp;
temp.size.width = fullScreenRect.size.height;
temp.size.height = fullScreenRect.size.width;
fullScreenRect = temp;
}
return fullScreenRect;
}
- (void)animationFinished:(NSString *)animationID finished:(BOOL)finished context:(void *)context
{
if ([animationID isEqualToString:#"expand"])
{
//example
}
else if ([animationID isEqualToString:#"collapse"])
{
//example
}
}
You could try adding a UIView (either in xib or programmatically) off screen, then use a UIView animation to slide it into your main viewing area.
The button would have an IBAction which would toggle the animation (slide in/slide out). You can slide it off screen then set UIView's hidden property to true. When you recall the IBAction, have it check if the view's hidden property is true. If it is, you know to play the animation of it sliding in, if not, then you play the animation of sliding out.