I know there is a similar question to this but I am not seeing what I am doing wrong when I compare my code to the other similar questions so can someone please help me understand what I am missing? I am getting an error from Xcode saying that there is an expected expression (for animations:{)
if (animated) {
[UIView animationWithDuration:0.30 animations:{
self.alpha = 1.0f;
if (animationType == MBProgressHUDAnimationZoomIn || animationType == MBProgressHUDAnimationZoomOut) {
self.transform = rotationTransform;
}
}];
}
The method is animateWithDuration, not animationWithDuration .
Your animations block is missing the caret: ^{
if (animated) {
[UIView animateWithDuration:0.30 animations:^{
self.alpha = 1.0f;
if (animationType == MBProgressHUDAnimationZoomIn || animationType == MBProgressHUDAnimationZoomOut) {
self.transform = rotationTransform;
}
}];
}
Related
I need to implement on my app a Slide menu (like the one on the facebook app) but i also wants to have buttons on my Views that links to other Views, for example on my Main View I have a button that on click goes to OptionView but i also want to have a slide menu That links to OptionView, i'm using storyboards and xcode 5 and I wanted to know if someone can help me to figure out how to create the Slide menu
You can either use this to have an idea / use the open source:
https://github.com/aryaxt/iOS-Slide-Menu
or you can implement it like this:
Add to your navigation bar a UIBarButtonItem:
UIBarButtonItem *rightRevealButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"reveal-icon.png"] style:UIBarButtonItemStyleBordered target: self action:#selector(rightRevealToggle:)];
self.navigationItem.rightBarButtonItem = rightRevealButtonItem;
implement the rightRevealToggle:
- (void)rightRevealToggle:(id)sender
{
float width = self.view.frame.size.width;
float height = self.view.frame.size.height;
self.navigationItem.rightBarButtonItem.enabled = FALSE;
CGRect rearViewFrame = _rearViewController.view.frame;
float deltaToMoveRearView = _rearViewController.datePicker.frame.size.width;//0.25f * width;
//slide the rear view inside
if(_rearViewController.view.hidden && ![sender isKindOfClass:[UISwipeGestureRecognizer class]])
{
_rearViewController.view.hidden = FALSE;
[UIView animateWithDuration:0.7f animations:^{
_rearViewController.view.frame = CGRectMake(width - deltaToMoveRearView,rearViewFrame.origin.y,rearViewFrame.size.width,rearViewFrame.size.height);
_contentViewController.view.frame = CGRectMake(-deltaToMoveRearView , 0, width, _contentViewController.view.frame.size.height);
NSLog(#"3: frame: x:%f y:%f",_contentViewController.view.frame.origin.x,_contentViewController.view.frame.origin.y);
} completion:^(BOOL finished){
self.navigationItem.rightBarButtonItem.enabled = TRUE;
}];
}
//slide the rear view outside
else
{
self.rearViewController.view.hidden = FALSE;
[UIView animateWithDuration:0.7f animations:^{
_rearViewController.view.frame = CGRectMake(width,rearViewFrame.origin.y,rearViewFrame.size.width,rearViewFrame.size.height);
_contentViewController.view.frame = CGRectMake(0, 0, width, _contentViewController.view.frame.size.height);
self.titleLabel.alpha = 1;
} completion:^(BOOL finished){
_rearViewController.view.hidden = finished;
self.navigationItem.rightBarButtonItem.enabled = TRUE;
}];
[self updateContentViewController];
}
}
- (void)updateContentViewController
{
UIViewController *newVC = [self.storyboard instantiateViewControllerWithIdentifier:[NSString stringWithFormat:#"%#VC",_rearViewController.selectedSection]];
if([newVC class] == [ScoresViewController class])
{
if([_contentViewController class] == [ScoresViewController class] &&
[((ScoresViewController *) _contentViewController) date] != _rearViewController.datePicker.date)
{
((ScoresViewController *) newVC).date = _rearViewController.datePicker.date;
[self cycleToViewController:newVC];
}
}
if([newVC class] != [_contentViewController class])
{
[self cycleToViewController:newVC];
}
}
see the below link with so many examples
Code4App Menu
I used this code many times but in my current project it isn't working. Here is the error (third line):
"No visible #interface for 'UIGestureRecognizer' declares the selector 'translationInView:'
and my simple code:
- (IBAction)panLayer:(UIGestureRecognizer *)pan{
if (pan.state == UIGestureRecognizerStateChanged) {
CGPoint point = [pan translationInView:self.view];
CGRect frame = self.settingsView.frame;
frame.origin.y = self.layerPosition + point.y;
if (frame.origin.y < 0) {
frame.origin.y = 0;
}
}
You are looking for the UIPanGestureRecognizer that has UIGestureRecognizer as the parent class.
- (IBAction)panLayer:(UIPanGestureRecognizer *)pan{
}
I am trying to create a custom view, which is similar to NSScrollView, but is based on CoreAnimation CAScrollLayer/CATiledLayer. Basically, my app requires a lot of near realtime CGPath drawing, and animates these paths using shape layers (it's similar to the way GarageBand animates while recording). The first prototype I created used NSScrollView, but I could not get more than 20 frames per second with it (The reason was that NSRulerView updates by drawing every time the scrollEvent happens, and the entire call flow from -[NSClipView scrollToPoint] to -[NSScrollView reflectScrolledClipView:] is extremely expensive and inefficient).
I've created a custom view that uses CAScrollLayer as scrolling mechanism and CATiledLayer as the traditional documentView (for infinite scrolling option), and now I can get close to 60fps. However, I'm having hard time implementing scrollWheel elastic scrolling, and I'm not sure how to do it. Here's the code I have so far, and would really appreciate if someone can tell me how to implement elasticScrolling.
-(void) scrollWheel:(NSEvent *)theEvent{
NSCAssert(mDocumentScrollLayer, #"The Scroll Layer Cannot be nil");
NSCAssert(mDocumentLayer, #"The tiled layer cannot be nil");
NSCAssert(self.layer, #"The base layer of view cannot be nil");
NSCAssert(mRulerLayer, #"The ScrollLayer for ruler cannot be nil");
NSPoint locationInWindow = [theEvent locationInWindow];
NSPoint locationInBaseLayer = [self convertPoint:locationInWindow
fromView:nil];
NSPoint locationInRuler = [mRulerLayer convertPoint:locationInBaseLayer
fromLayer:self.layer];
if ([mRulerLayer containsPoint:locationInRuler]) {
return;
}
CGRect docRect = [mDocumentScrollLayer convertRect:[mDocumentLayer bounds]
fromLayer:mDocumentLayer];
CGRect scrollRect = [mDocumentScrollLayer visibleRect];
CGPoint newOrigin = scrollRect.origin;
CGFloat deltaX = [theEvent scrollingDeltaX];
CGFloat deltaY = [theEvent scrollingDeltaY];
if ([self isFlipped]) {
deltaY *= -1;
}
scrollRect.origin.x -= deltaX;
scrollRect.origin.y += deltaY;
if ((NSMinX(scrollRect) < NSMinX(docRect)) ||
(NSMaxX(scrollRect) > NSMaxX(docRect)) ||
(NSMinY(scrollRect) < NSMinY(docRect)) ||
(NSMaxY(scrollRect) > NSMaxX(docRect))) {
mIsScrollingPastEdge = YES;
CGFloat heightPhase = 0.0;
CGFloat widthPhase = 0.0;
CGSize size = [self frame].size;
if (NSMinX(scrollRect) < NSMinX(docRect)) {
widthPhase = ABS(NSMinX(scrollRect) - NSMinX(docRect));
}
if (NSMaxX(scrollRect) > NSMaxX(docRect)) {
widthPhase = ABS(NSMaxX(scrollRect) - NSMaxX(docRect));
}
if (NSMinY(scrollRect) < NSMinY(docRect)) {
heightPhase = ABS(NSMinY(scrollRect) - NSMinY(docRect));
}
if (NSMaxY(scrollRect) > NSMaxY(docRect)) {
heightPhase = ABS(NSMaxY(scrollRect) - NSMaxY(docRect));
}
if (widthPhase > size.width/2.0) {
widthPhase = size.width/2.0;
}
if (heightPhase > size.width/2.0) {
heightPhase = size.width/2.0;
}
deltaX = deltaX*(1-(2*widthPhase/size.width));
deltaY = deltaY*(1-(2*heightPhase/size.height));
}
newOrigin.x -= deltaX;
newOrigin.y += deltaY;
if ( mIsScrollingPastEdge &&
(([theEvent phase] == NSEventPhaseEnded) ||
([theEvent momentumPhase] == NSEventPhaseEnded)
)
){
CGPoint confinedScrollPoint = [mDocumentScrollLayer bounds].origin;
mIsScrollingPastEdge = NO;
CGRect visibleRect = [mDocumentScrollLayer visibleRect];
if (NSMinX(scrollRect) < NSMinX(docRect)){
confinedScrollPoint.x = docRect.origin.x;
}
if(NSMinY(scrollRect) < NSMinY(docRect)) {
confinedScrollPoint.y = docRect.origin.y;
}
if (NSMaxX(scrollRect) > NSMaxX(docRect)) {
confinedScrollPoint.x = NSMaxX(docRect) - visibleRect.size.width;
}
if (NSMaxY(scrollRect) > NSMaxY(docRect)){
confinedScrollPoint.y = NSMaxY(docRect) - visibleRect.size.height;
}
[mDocumentScrollLayer scrollToPoint:confinedScrollPoint];
CGPoint rulerPoint = [mRulerLayer bounds].origin;
rulerPoint.x = [mDocumentLayer bounds].origin.x;
[mRulerLayer scrollToPoint:rulerPoint];
return;
}
CGPoint rulerPoint = [mDocumentScrollLayer convertPoint:newOrigin
toLayer:mRulerLayer];
rulerPoint.y = [mRulerLayer bounds].origin.y;
if (!mIsScrollingPastEdge) {
[CATransaction setDisableActions:YES];
[mDocumentScrollLayer scrollToPoint:newOrigin];
[CATransaction commit];
}else{
[mDocumentScrollLayer scrollToPoint:newOrigin];
[mRulerLayer scrollToPoint:rulerPoint];
}
}
Take a look at TUIScrollView at https://github.com/twitter/twui.
The Core concept of adding ElasticScrolling is to use a SpringSolver.
This has a ElasticScrollView that you can reuse:
https://github.com/eonist/Element
I'm trying to add an effect to a switch between 2 views. The switch happen just rotating the device. So far I'm able to apply the effect when from portrait go to landscape, but not viceversa.
Here's my code:
-(void)orientationChanged:(NSNotification *)object{
UIDeviceOrientation deviceOrientation = [[object object] orientation];
if (deviceOrientation == UIInterfaceOrientationPortrait)
{
/* If I run with this block, I have a Exc Bad Access Error and can't run, so I put it
under comment
[UIView transitionWithView:self.view duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self.view addSubview:self.portraitView];
} completion:NULL];
*/
self.view = self.portraitView;
//[self dismissModalViewControllerAnimated:YES];
}
else if (deviceOrientation == UIInterfaceOrientationLandscapeLeft || deviceOrientation ==
UIInterfaceOrientationLandscapeRight)
{
[UIView transitionWithView:self.view duration:1
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self.view addSubview:self.landscapeView];
} completion:NULL];
[self dismissModalViewControllerAnimated:NO];
}
}
In this way I have the desired effect when passing from Portrait to Landscape, but when I put the device back to Portrait it doesn't load the portraitView, the landscapeView remains on.
Hope somebody can help me.
EDIT:
I just edited my above code in this way:
-(void)orientationChanged:(NSNotification *)object{
UIDeviceOrientation deviceOrientation = [[object object] orientation];
if (deviceOrientation == UIDeviceOrientationPortrait)
{
if (self.isViewLoaded && self.view.window)
{
NSLog(#"Portrait1");
[UIView transitionWithView:self.view duration:1
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
NSLog(#"Portrait2");
[self.view.window addSubview:self.portraitView];
} completion:NULL];
[self dismissModalViewControllerAnimated:YES];
}
}
else if (deviceOrientation == UIDeviceOrientationLandscapeLeft || deviceOrientation ==
UIDeviceOrientationLandscapeRight)
{
[UIView transitionWithView:self.view duration:1
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
[self.view addSubview:self.landscapeView];
} completion:NULL];
[self dismissModalViewControllerAnimated:NO];
NSLog(#"Landscape");
}
}
And the effect works fine. But I have the big issue that when I switch back from Landscape to Portrait the landscapeView remains ON the portraitView. How could I dismiss it?
Referring to your updated code, when your device orientation becomes UIDeviceOrientationPortrait, you are making the mistake of adding portraitView as a subview to self.view.window instead of self.view.
Also, what is the purpose behind [self dismissModalViewControllerAnimated:NO]? You haven't actually presented a modal view controller anywhere, so it doesn't serve any purpose.
I'm trying to animate an indicator to an empty form field so I'm using the method below to animate to a position, reverse the animation, and repeat. In the simulator this works fine, on my 3GS it looks like there is a flicker right when the completion block is called. The indicator is briefly shown at the middle position rather than back at it's origin.
Any thoughts on why this is happening? Thanks.
- (void)bounceFormIndicator {
if (formIndicator.superview == nil) {
return;
}
int bounceDistance = 24;
[UIView animateWithDuration:0.6
delay:0
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction
animations:^{
CGRect indicatorFrame = formIndicator.frame;
indicatorFrame.origin.x += bounceDistance;
formIndicator.frame = indicatorFrame;
}completion:^(BOOL finished){
CGRect indicatorFrame = formIndicator.frame;
indicatorFrame.origin.x -= bounceDistance;
formIndicator.frame = indicatorFrame;
[self bounceFormIndicator];
}];
}
I had the same problem, and went to Apple DTS to help with a workaround.
As per DTS, this 'flickering' effect, or snap-back effect is the expected behaviour... I thought that I was doing something wrong with my project for a long time.
In particular it is this way because the documentation states, for
UIViewAnimationOptionAutoreverse Run the animation backwards and
forwards.
Must be combined with the UIViewAnimationOptionRepeat option.
In order to get the flicker to go away, I had to do 2 things.
My implementation was dynamic, so you might not have to implement the first step, but I'll keep it in here just for reference.
First, I checked to see if UIViewAnimationOptionAutoreverse was part of the options I was going to pass into my animation, and UIViewAnimationOptionRepeat was not... If so, I stripped it from the options by adding a line like:
animationOptions &= ~UIViewAnimationOptionAutoreverse;
To create the reversing animation without repeating, I added an opposite UIView animation as my completion block. I also inverted the easing if it was either UIViewAnimationOptionCurveEaseIn or UIViewAnimationOptionCurveEaseOut...
The code from my project follows:
The statement that strips the autoreverse option from an object's animationOptions:
if ((animationOptions & AUTOREVERSE) == AUTOREVERSE) {
self.shouldAutoreverse = YES;
animationOptions &= ~AUTOREVERSE;
}
An example of an overridden property setter that handles an animation:
-(void)setCenter:(CGPoint)center {
CGPoint oldCenter = CGPointMake(self.center.x, self.center.y);
void (^animationBlock) (void) = ^ { super.center = center; };
void (^completionBlock) (BOOL) = nil;
BOOL animationShouldNotRepeat = (self.animationOptions & REPEAT) != REPEAT;
if(self.shouldAutoreverse && animationShouldNotRepeat) {
completionBlock = ^ (BOOL animationIsComplete) {
[self autoreverseAnimation:^ { super.center = oldCenter;}];
};
}
[self animateWithBlock:animationBlock completion:completionBlock];
}
The completion method called for in the case of reversing without repeating:
-(void)autoreverseAnimation:(void (^)(void))animationBlock {
C4AnimationOptions autoreverseOptions = BEGINCURRENT;
if((self.animationOptions & LINEAR) == LINEAR) autoreverseOptions |= LINEAR;
else if((self.animationOptions & EASEIN) == EASEIN) autoreverseOptions |= EASEOUT;
else if((self.animationOptions & EASEOUT) == EASEOUT) autoreverseOptions |= EASEIN;
[UIView animateWithDuration:self.animationDuration
delay:0
options:autoreverseOptions
animations:animationBlock
completion:nil];
}