enumeration values 'UIGestureRecognizerStatePossible', 'UIGestureRecognizerStateCancelled', and 'UIGestureRecognizerStateFailed' not handled in switch - objective-c

When i using gesture functionality for flip up and down this is occurred kindly help to fix this error
- (void)doFlipForward:(UIGestureRecognizer *)aGestureRecognizer forOrientation:(UIInterfaceOrientation)anOrientation{
if(isAnimating)
return;
switch([aGestureRecognizer state])//There is occurred in this line
{
case UIGestureRecognizerStateBegan:
[CATransaction begin];
[CATransaction setDisableActions:YES];
[flipPage setHidden:NO];
[flipShadow setHidden:NO];
[CATransaction commit];
break;
case UIGestureRecognizerStateChanged:
{
CGFloat multiplier = 0.0f;
if(UIInterfaceOrientationIsPortrait(anOrientation))
{
multiplier = portraitMultiplierTable[(NSInteger)[aGestureRecognizer locationInView:self].x];
[thisPage setPortraitCurlAnimationPosition:multiplier];
[flipPage setPortraitCurlAnimationPosition:multiplier];
[flipShadow setPortraitCurlAnimationPosition:multiplier];
}
else
{
multiplier = landscapeMultiplierTable[(NSInteger)[aGestureRecognizer locationInView:self].x];
[thisPage setLandscapeCurlAnimationPosition:multiplier];
[flipPage setLandscapeCurlAnimationPosition:multiplier];
[flipShadow setLandscapeCurlAnimationPosition:multiplier];
}
}
break;
case UIGestureRecognizerStateEnded:
{
CGFloat transX = [(UIPanGestureRecognizer *)aGestureRecognizer translationInView:self].x;
CGFloat width = [self bounds].size.height * PAGE_RATIO;
if(width + transX < width/2)
{
[self animateOpen];
}
else
{
[self animateClose];
}
}
break;
}
}

You don't have a case for the listed values in the warning. Add the following to silence the warning:
default:
break;

Related

iOS: How to drag a view along with finger till a particular y offset?

I am dragging a view from bottom to top with pre-defined offset positions using pan gesture.
My current implementation is such that the view updates after the gesture has ended. However, I want the view to update along with the finger (gesture is ongoing) and stop at the predefined (next) position when the gesture has ended.
Would appreciate if somebody could point me in the right direction. Thank you.
m_openPercentage = #"30,60";
- (void)onContentViewPanned:(UIPanGestureRecognizer *)gesture
{
CGPoint velocity = [gesture velocityInView:self.view];
NSArray *m_Openpercentage = [m_OpenPercentage componentsSeparatedByString:#","];
NSMutableArray *fullpercentage = [NSMutableArray arrayWithArray:m_Openpercentage];
float diffy = 0.0;
if(([gesture state] == UIGestureRecognizerStateEnded))
{
if(velocity.y < 0)
{
if(m_isfullscreen && ![fullpercentage containsObject:#"100"])
{
[fullpercentage addObject:#"100"];
}
diffy = 1-([[fullpercentage objectAtIndex:counter] floatValue]/100);
CGFloat ypos = self.view.frame.size.height * diffy;
[UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0.5 options:0 animations:^{
[self.view setNeedsLayout];
self.view.frame = CGRectMake(0,ypos,self.view.frame.size.width,self.view.frame.size.height);
if(self.view.frame.origin.y==0)
[self showNavigationbar:1];
} completion:^(BOOL finished) {
}];
if(counter<[fullpercentage count]-1)
counter++;
}
else
{
if(counter>0)
{
float diffy = 1-([[fullpercentage objectAtIndex:counter-1] floatValue]/100);
CGFloat ypos = self.view.frame.size.height * diffy;
[UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0.5 options:0 animations:^{
self.view.frame = CGRectMake(0,ypos,self.view.frame.size.width,self.view.frame.size.height);
} completion:^(BOOL finished) {
}];
}
else
{
diffy = 1-(m_initialPercentage/100);
CGFloat ypos = self.view.frame.size.height * diffy;
if(self.view.frame.origin.y < ypos)
{
[UIView animateWithDuration:1 delay:0 usingSpringWithDamping:0.5 initialSpringVelocity:0.5 options:0 animations:^{
self.view.frame = CGRectMake(0,ypos,self.view.frame.size.width,self.view.frame.size.height);
} completion:^(BOOL finished) {
}];
}
else
{
[self removeoverlayview];
[self.view removeFromSuperview];
id tmpControllerObj = [parentController getParentController];
[tmpControllerObj view].userInteractionEnabled = YES;
}
}
if((counter-1)>=0)
counter--;
[self showNavigationbar:0];
}
if(![m_Openpercentage containsObject:#"100"] && m_isfullscreen)
[self updatefullview];
}
}

CAShapeLayer Path Animation

I'm trying to animate a path change on a particular shape. I can manually change without animation by replacing this code with a simple .path [cgpath] setter. However, I want to animate the change for aesthetics.
When this code executes, there is no change to the shape what-so-ever although the log suggests the animation is complete.
for (CALayer *layer in self.view.layer.sublayers) {
if ([layer isKindOfClass:[CAShapeLayer class]]) {
CAShapeLayer *copy = (CAShapeLayer *)layer;
if ([sideChoice isEqualToString:#"datum"]) {
if ([copy.name isEqualToString:#"datumSideLayer"]) {
[CATransaction begin];
[CATransaction setCompletionBlock:^{
NSLog(#"Animation complete.");
}];
CABasicAnimation *morph = [CABasicAnimation animationWithKeyPath:#"path"];
morph.duration = 1;
morph.toValue = pathChange;
[copy addAnimation:morph forKey:nil];
[CATransaction commit];
break;
}
} else if ([sideChoice isEqualToString:#"opposite"]) {
if ([copy.name isEqualToString:#"oppositeSideLayer"]) {
}
}
}
}
for (CALayer *layer in self.view.layer.sublayers) {
if ([layer isKindOfClass:[CAShapeLayer class]]) {
CAShapeLayer *copy = (CAShapeLayer *)layer;
if ([sideChoice isEqualToString:#"datum"]) {
if ([copy.name isEqualToString:#"datumSideLayer"]) {
[CATransaction begin];
[CATransaction setCompletionBlock:^{
NSLog(#"Animation complete.");
}];
CABasicAnimation *morph = [CABasicAnimation animationWithKeyPath:#"path"];
morph.duration = 1;
morph.fromValue = (id) copy.path;
morph.toValue = (id) pathChange.CGPath;
[copy addAnimation:morph forKey:nil];
copy.path = [pathChange CGPath];
[CATransaction commit];
break;
}
} else if ([sideChoice isEqualToString:#"opposite"]) {
if ([copy.name isEqualToString:#"oppositeSideLayer"]) {
}
}
}
}
I didn't correctly set a fromValue nor was I pointing to a CGPath.

i have lots of if else condition how to reduce them

I have a text field and used numberOfRowsInSection for creating more than 50 text fields. After that I use the if else condition, but it was time consuming and a lengthy method so I want to reduce my if else condition. I don't want to use the switch condition. What should I do?
if (textField.tag == 0)//cust add line 1
{
[_customerFormTableView setContentOffset : CGPointMake(0, 0)];
}
else if (textField.tag == 1)//cust add line 2
{
[_customerFormTableView setContentOffset : CGPointMake(0, 0)];
}
else if (textField.tag == 2)//kyc line 1
{
[_customerFormTableView setContentOffset : CGPointMake(0, 50)];
}
else if (textField.tag == 3)// kyc line 2
{
[self.view endEditing : YES];
DatePickerViewController *dateViewContrl = [self.storyboard instantiateViewControllerWithIdentifier : #"DatePickerViewController"];
dateViewContrl.delegate = self;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
{
//dateViewContrl.preferredContentSize=CGSizeMake(325, 200);
dateViewContrl.preferredContentSize = CGSizeMake(290, 200);
}
popcontrol = [[WYPopoverController alloc] initWithContentViewController:dateViewContrl];
[popcontrol.delegate self];
// _currentfield=_dateTextField;
NSLog(#"%f %f",popcontrol.popoverContentSize.height,popcontrol.popoverContentSize.height);
CGRect rect_ = [self.view convertRect : textField.frame fromView : textField.superview];
[popcontrol presentPopoverFromRect : rect_
inView : self.view
permittedArrowDirections : WYPopoverArrowDirectionAny
animated : YES
options : WYPopoverAnimationOptionScale];
return NO;
}
else if (textField.tag == 4)
{
[textField resignFirstResponder];
[self DropDownGendview : textField];
return NO;
}
else if (textField.tag == 5)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 250)];
}
else if (textField.tag == 6)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 310)];
}
else if (textField.tag == 7)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 370)];
}
else if (textField.tag == 8 || textField.tag == 13 || textField.tag == 20)
{
[self.view endEditing : YES];
[self DropDownview : textField];
return NO;
}
else if (textField.tag == 9)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 510)];
}
else if (textField.tag == 10)//cor email
{
[_customerFormTableView setContentOffset : CGPointMake(0, 630)];
}
else if (textField.tag == 11)//desig
{
[_customerFormTableView setContentOffset : CGPointMake(0, 700)];
}
else if (textField.tag == 12)//level
{
[_customerFormTableView setContentOffset : CGPointMake(0, 770)];
}
else if (textField.tag == 14)//level
{
[_customerFormTableView setContentOffset : CGPointMake(0, 910)];
}
else if (textField.tag == 15)//level
{
[_customerFormTableView setContentOffset : CGPointMake(0, 980)];
}
else if (textField.tag == 16)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1050)];
}
else if (textField.tag == 17)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1140)];
}
else if (textField.tag == 18)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1240)];
}
else if (textField.tag == 19)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1310)];
}
else if (textField.tag == 21)
{
NSLog(#"state dropdown %ld",(long)textField.tag);
}
else if (textField.tag == 22)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1520)];
}
else if (textField.tag == 23)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1590)];
}
else if (textField.tag == 24)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1660)];
}
else if (textField.tag == 25)
{
[_customerFormTableView setContentOffset : CGPointMake(0, 1730)];
}
else if (textField.tag == 26)
{
[self.view endEditing : YES];
[self dropDownPurposeView : textField];
return NO;
}
You can represent a lot of these if statements with data, using a struct:
typedef struct
{
int tag;
int pointX;
int pointY;
} Values;
const Values values[] = {
{0, 0, 0},
{1, 0, 0},
{2, 0, 50},
// etc
};
then iterate through values and determine if your tag is in it:
int i;
bool found = false;
for (i = 0; i < sizeof(values) / sizeof(values[0]); i++)
{
if (values[i].tag == textField.tag)
{
[_customerFormTableView setContentOffset: CGPointMake(values[i].pointX,
values[i].pointY)];
found = true;
break;
}
}
if (! found)
{
// do more complicated operations here
}
you can speed up the for statement with a binary search, if the tags are sorted.
You can try with switch case statement.It is better one instead of having lots of if else condition.If you use swit case it will improve your performance rather than having multiple if else condition.
A switch statement allows a variable to be tested for equality against a list of values. Each value is called a case, and the variable being switched on is checked for each switch
switch(expression){
case constant-expression :
statement(s);
break; /* optional */
case constant-expression :
statement(s);
break; /* optional */
/* you can have any number of case statements */
default : /* Optional */
statement(s);
}
Generally the expression used in a switch statement must have an integral or enumerated type or be of a class type in which the class has a single conversion function to an integral or enumerated type.
For more details go with this https://www.tutorialspoint.com/objective_c/switch_statement_in_objective_c.htm

Animating UINavigationBar in iOS 7 (like Safari)

When scrolling content in Safari, the title bar animates to a smaller version of its self. What is the best way to implement this?
Currently, I am changing the size of the frame like so:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//
// Table view
//
CGFloat currentPosition = scrollView.contentOffset.y - CGRectGetHeight(self.tableView.tableHeaderView.frame) + CGRectGetHeight(self.navigationController.navigationBar.frame) + CGRectGetHeight([[UIApplication sharedApplication] statusBarFrame]);
if ([scrollView isKindOfClass:[HeadlinesHeadlinesTableView class]]) {
ScrollDirection scrollDirection;
if (self.lastContentOffset > scrollView.contentOffset.y) {
scrollDirection = ScrollDirectionDown;
} else if (self.lastContentOffset < scrollView.contentOffset.y) {
scrollDirection = ScrollDirectionUp;
}
self.lastContentOffset = scrollView.contentOffset.y;
CGRect frame = self.navigationController.navigationBar.frame;
CGFloat minimumFrameHeight = 30.0f;
CGFloat maximumFrameHeight = 44.0f;
CGFloat titleSize = [[self.navigationController.navigationBar.titleTextAttributes objectForKey:NSFontAttributeName] pointSize];
CGFloat minimumTitleHeight = 22.0f;
CGFloat maximumTitleHeight = 30.0f;
if (currentPosition > 0 && CGRectGetHeight(frame) >= minimumFrameHeight && CGRectGetHeight(frame) <= maximumFrameHeight) {
switch (scrollDirection) {
case ScrollDirectionUp:
frame.size.height--;
titleSize--;
break;
case ScrollDirectionDown:
frame.size.height++;
titleSize++;
break;
default:
break;
}
if (CGRectGetHeight(frame) <= minimumFrameHeight) {
frame.size.height = minimumFrameHeight;
}
if (CGRectGetHeight(frame) >= maximumFrameHeight) {
frame.size.height = maximumFrameHeight;
}
if (titleSize <= minimumTitleHeight) {
titleSize = minimumTitleHeight;
}
if (titleSize >= maximumTitleHeight) {
titleSize = maximumTitleHeight;
}
}
[self.navigationController.navigationBar setFrame:frame];
[self.navigationController.navigationBar setTitleTextAttributes: #{ NSFontAttributeName : [UIFont fontWithName:#"Canterbury-Regular" size:titleSize] }];
}
}
Naturally, this way is not smooth and a lot of code, not to mention the fact that I need to fade out bar button items as well.
Thanks in advance!
Take a look at AMScrollingNavbar, it already has fading support.
You can try to change font size of NavigationBar to make the title smaller.

iOS find if a view is animating

I'm trying to animate (fade in/out) a UILabel and I'm using the following code:
float newAlpha = 0.0;
//TODO:Check if the previous animation has finished
if(answer.alpha==0.0) {
newAlpha = 1.0;
} else if(answer.alpha==1.0) {
newAlpha = 0.0;
}
[UIView animateWithDuration:1.0 animations:^{
answer.alpha = newAlpha;
}];
Where the TODO comment is, I want to check if the previous animation has finished and if it hasn't, exit the method. Is there some way of doing this?
UPDATE #1:
you need a variable in your class:
BOOL _animationFinished;
and then you can use the following way for the animation:
float newAlpha = 0.0;
//TODO:Check if the previous animation has finished
if (_animationFinished == false) return;
if(answer.alpha==0.0) {
newAlpha = 1.0;
} else if(answer.alpha==1.0) {
newAlpha = 0.0;
}
[UIView animateWithDuration:1.0f animations:^{ answer.alpha = newAlpha; _animationFinished = false; } completion:^(BOOL finished){ _animationFinished = true; }];
it must be work.
ORIGINAL
I'm always checking the subject of the animation in this case, like this:
float newAlpha = 0.0;
//TODO:Check if the previous animation has finished
if (answer.alpha > 0.f || answer.alpha < 1.f) return; // it is always good enough for me
// ...or with AND it will cause the same effect:
// if (answer.alpha > 0.f && answer.alpha < 1.f) return;
if(answer.alpha==0.0) {
newAlpha = 1.0;
} else if(answer.alpha==1.0) {
newAlpha = 0.0;
}
[UIView animateWithDuration:1.0 animations:^{
answer.alpha = newAlpha;
}];
If you're using UIView then
[UIView setAnimationDidStopSelector:#selector(animationfinished)];
-(void) animationfinished
{
animationFinished = YES;
}
Use animateWithDuration:animations:completion: method to do your "previous animation", and set a flag in the completion handler to indicate if it's finished or not. Then, check the same flag exactly where you have the TODO comment.
Edit: Example below
-(void) animation1 {
// assume that alpha was 0 and we want the view to appear
[UIView animateWithDuration:1.0 animations:^{
answer.alpha = 1.0;
} completion:^(BOOL finished){
fristAnimationFinished = finished;
}];
}
-(void) animation2 {
float newAlpha = 0.0;
if (!firstAnimationFinished)
return;
if(answer.alpha==0.0) {
newAlpha = 1.0;
} else if(answer.alpha==1.0) {
newAlpha = 0.0;
}
[UIView animateWithDuration:1.0 animations:^{
answer.alpha = newAlpha;
}];
}