iOS Using Partial Page Curl on UIView, NOT UIViewController - ios

I've got a MainViewController that has many subViews. Basically, it's broken down into two panes. The panes are designed to look like clipboards. I'd like to hit a button and have the "paper" on one of the clipboards do a partial curl to reveal the page underneath.
This isn't a full Modal ViewController presentation situation.
I'm working with the following code, but the results are funky:
FlipView *flipView = [[FlipView alloc] init];
[self setFlipView:flipView];
[flipView setHidden:YES];
[flipView setFrame:[[self WhereAmI] frame]];
[[self view] addSubview:flipView];
[[self view] bringSubviewToFront:[self WhereAmI]];
[flipView setHidden:NO];
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setDuration:1.0];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[animation setType:#"pageCurl"];
[animation setFillMode:kCAFillModeForwards];
[animation setEndProgress:0.9];
[animation setRemovedOnCompletion:NO];
[[self WhereAmI] setHidden:YES];
[[[self WhereAmI] layer] addAnimation:animation forKey:#"pageCurlAnimation"];
Basically, I'm trying to load my new view programmatically, slide it in behind the currently visible view and then curl up the view that's on top to reveal the view that's now underneath. I get somewhat of a partial curl animation, but the "page" that's curling up isn't opaque, which is odd. Also, when I don't set my view and label to be hidden, even though you see them curl up, you also still see them "underneath", which is also odd. Plus, I don't see the UILabel I placed in the XIB for the new view.
Any thoughts?
Thanks!
OK, so I've got a working solution, but it's not quite what I was hoping to do. I'd still love to figure out the solution to my original question, but here's what I'm doing for now:
The background image for my "base" view is an image of a spiral-bound notebook.
The background image for all other views is a screen shot of a page curl.
(By "background image", I mean a UIColor created with a patternImage.)
The code to transition views is:
- (IBAction)NavigationTabSelected:(id)sender
{
// Flipping views is driven by a SegmentedControl
int selected = [[self NavigationTabsSegmentedControl] selectedSegmentIndex];
int current = [[self ViewArray] indexOfObject:[self ActiveFlipView]];
UIView *newFlip = [[self ViewArray] objectAtIndex:selected];
BOOL up = selected > current;
[UIView animateWithDuration:1.0
animations:^{
[UIView setAnimationTransition:(up)?UIViewAnimationTransitionCurlUp:UIViewAnimationTransitionCurlDown forView:[self RightView] cache:YES];
[[self ActiveFlipView] removeFromSuperview];
[[self RightView] addSubview:newFlip];
}
completion:^(BOOL finished){
[self setActiveFlipView:newFlip];
}];
}
As you can see, tabs to the right of the current tab generate a "curl up" and tabs to the left of the current tab generate a "curl down". It's not quite what I wanted, but it serves my purpose.
Any better ideas?

have you considered loading it as a modal view?
- (void)yourFrontViewControllerMethod
{
YourBackViewController *bfvc = [[YourBackViewController alloc] init];
[bfvc setModalTransitionStyle:UIMoalTransitionStylePartialCurl];
[self presentViewController:bfvc];
[bvfc release];
}
This will give you the desired effect of a view curling up to reveal another view.
Also as a general rule of thumb we try not to create animations that way. Try using a block based method instead (eg [UIView AnimateWithDuration:....]);
Hope that helps :)

Related

iOS 9: push/pop view controller broken by edgesForExtendedLayout

I have found a strange issue while debugging on iOS 9. In my View Controller's viewDidLoad I have this piece of code:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
When I am pushing or popping a new view controller I have noticed a strange animation. The transition isn't smooth and it seems like it is displaying a "stack" of view controllers (you can notice the top and even slightly a bottom of both images).
I had no problem on iOS 7 or iOS8, is this a bug of the newly released iOS 9 or am I missing something?
It's also worth to mention that I am using custom animation for push/pop view controller transition.
Here is an example of one of the overriden UINavigationController methods
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
UIView *theWindow = self.view;
[[theWindow layer] removeAllAnimations];
if (animated) {
CATransition *animation = [CATransition animation];
[animation setDuration:0.25];
[animation setType:kCATransitionFade];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
[[theWindow layer] addAnimation:animation forKey:#""];
}
[super pushViewController:viewController animated:NO];
}
EDIT:
I have been debugging this issue for couple of hours now. I have reimplemented the custom animations following API for view controllers transitions introduced in iOS 7 (navigationController:animationControllerForOperation:operation fromViewController:toViewController) but the issue persists.
The problem happens if the transition is animating alpha property.
Do you have an idea how to overcome this issue?
Thanks.
You need to setup final frame for toViewController. transitionContext.finalFrame(for:) can help you to determine it. Something like:
toViewController.view.frame = transitionContext.finalFrame(for: toViewController)

How to add multiview to a screen?

I have an application of proof of simulated, which have some modules, and one of this is a screen which need be reloaded for exhibition of same data. Example: I have screen of the question and answers. Like below
Question: bla bla bla?
Item A: X
Item B: Y
Item c: Z
...
the screen remains the same, what needs to be change is the question and answer content item A, item B, etc..
And, I'm loading the informations "hardcode". I'm sure there are other better choice to make this ^^. I would like to use the same screen to load the features. How I can make this? I was looking to page controller, but it's not what I want, I would like to use a navigation controller to navigation with the screens. I have a dictionary of a list of all the questions with answers: itemA, itemB, etc. how I can load this in the "same screen" with the option of next > and < previous?
A simple one solution is create one UIView add all question and answer related views in it.
Create one UIView add all question and answer related views in it
Create next/previous UIButtons
Add and remove this view on next/previous events and reload inner view content.
Use below method for animation which looks like a navigation next/previous
In below method self.questionPaperView is a which will be animated and it contains all question and answer related views.
Note: Create a global variable for questionPaperView and for inner views. So you don't need to add questions/answers subviews every time you add/remove questionPaperView.
- (void) removeQuestionPaper {
[UIView animateWithDuration:0.35f animations:^{
[self.questionPaperView removeFromSuperview];
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
// Call data reload method here.
}];
}
- (void) addQuestionPaper {
[self.view addSubview:self.questionPaperView]
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionFade];
[animation setSubtype:kCATransitionFromRight]; // For previous use kCATransitionFromLeft
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[theWindow layer] addAnimation:animation forKey:#"NextView"];
}

custom sidebar in ios7

i am new in iOS development and facing little issue.i don't know this approach is good or bad but i not want to used any third party.I want to make sidebar like Facebook sidebar and my code is
- (IBAction)basicProfile:(id)sender {
menuViewController *destVC = [self.storyboard instantiateViewControllerWithIdentifier:#"menuView"];
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
CGRect view = self.view.frame;
view.origin.x = 280;
if(self.view.frame.origin.x > 100 )
{
[UIView beginAnimations:nil context:(__bridge void *)(self.scrollView)];
[UIView setAnimationDuration:0.25];
NSLog(#"%f", self.view.frame.origin.y);
self.view.frame = CGRectMake(0,0,320,568);
[UIView commitAnimations];
}
else{
[self.showView setHidden:NO];
[UIView beginAnimations:nil context:(__bridge void *)(self.scrollView)];
[UIView setAnimationDuration:0.25];
NSLog(#"%f", self.view.frame.origin.y);
self.view.frame = CGRectMake(280,0,320,568);
[UIView commitAnimations];
[self.view addSubview:destVC.view]; // this line added menuView to profile view but not on sidebar
}
}
i have two uiview in storyborad one is profile and other is menuViewController.why menuView not loaded properly
result of above code
There are 2 approaches to do this:
Using 2 UIViews on the Same controller. You can add your MenuView along with your view and initial keep it hidden. Use a button to toggle to show/hide the Menu. It will be just like xview.hidden = TRUE / xview.hidden = FALSE to show/hide the view. You can use animation to give it a menu like appearance.
Use a different view controller for MenuDisplay and add it to the current view controllers like [xview addsubView:menuview.view] and [menuview.view removefromsuperview]
Step 01: Basically what you need is a viewController and 2 views (1 for sidebar and another the main view.)
Step 02 : You would than require to add both these views to the View Controller.
Step 03 : And than add a button to toggle using below:
-
(void)OnCollapsibleExtenderTouchUpInside
{
[UIView animateWithDuration:1.0 animations:^{
[sideBarObj ToggleVuPosition];
[mainVuObj ToggleVuSize];
}];
}
Note : There is already a explanation on stack overflow
You can follow this one:
Sidebar menu implementation on iOS like Facebook?
If your requirement is different, Do post comment.

Creating transitions on the navigation stack that show both source and destination views?

The native push transition shows the source view, and the transition over to the destination view seamlessly.
The modal transition shows the destination view overlaying the source view from the bottom.
I'd like a modal transition that works with the navigation controller.
So far I have this:
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:#"transform.translation.y"];
anim.duration = .2;
anim.autoreverses = NO;
anim.removedOnCompletion = YES;
anim.fromValue = [NSNumber numberWithInt:sourceViewController.view.frame.size.height];
anim.toValue = [NSNumber numberWithInt:0];
[sourceViewController.navigationController.view.layer addAnimation:anim
forKey:kCATransition];
[sourceViewController.navigationController pushViewController:destinationController animated:NO];
This is in the -perform method in my segue subclass. The problem with this is that the navigation controller push is done almost immediately, and while the transition takes place, nothing of the source view is displayed. I want it to look as if it's overlaying.
I thought it might be possible to take a screenshot using Core Graphics and having that as a superview of the destination view, but I couldn't get it to work properly.
I also tried using one of the UIView animation methods like so:
[sourceViewController.view addSubview:destinationController.view];
[destinationController.view setFrame:sourceViewController.view.window.frame];
[destinationController.view setTransform:CGAffineTransformMakeTranslation(0, sourceViewController.view.frame.size.height)];
[destinationController.view setAlpha:1.0];
[UIView animateWithDuration:1.3
delay:0.0
options:UIViewAnimationOptionTransitionNone
animations:^{
[destinationController.view setTransform:CGAffineTransformMakeTranslation(0, 0)];
[destinationController.view setAlpha:1.0];
}
completion:^(BOOL finished){
[destinationController.view removeFromSuperview];
[sourceViewController.navigationController pushViewController:destinationController animated:NO];
}];
But again, there's an issue with this: the navigation bar isn't displayed until the view controller is actually pushed onto the navigation stack. So there's a sort of "jump" at the end of the animation when the navigation bar is suddenly displayed.
So what are my options with this?
I resolved this by taking the route of creating an image of the source view and transitioning over that.
Also, it should be noted that the "flash" doesn't exist on ios 7 so there isn't much custom code necessary.

iOS Slide an UIView (Menu) from a side in another View

i want to slide in a menu from a side in a View after a buttonclick event. After another Buttonclick the menu should be slided out from the big View...
I experimented with CATransition but i can't solve this problem...
CATransition *animation = [CATransition animation];
[animation setDuration:1];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromBottom];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]] ;
[[menuView layer] addAnimation:animation forKey:#"#asdf"];
[menuView setCenter:CGPointMake([menuView center].x, [menuView center].y + 450)];
it work a bit, but i did not understand why.. :-/
If you want to implement it yourself one way you can go about it is create a custom view and add a button click event for a button in your view controller.
Also create a boolean variable to identify whether your custom view is visible or not.
On click, if menu view is not visible, then do this:
-(void)viewDidLoad
{
...
// ---------------------------------------------
// create the custom menu view off screen
// ---------------------------------------------
menuView = [[MenuView alloc] initWithFrame:CGRectMake(-320, 0, 320, 480)];
menuView.alpha = 0; // hide it so it doesn't show at the start, only show when slide in
[self.view addSubview:menuView];
...
}
-(void)toggleMenu
{
if(menuIsVisible)
{
menuIsVisible = NO;
[self hideMenu];
}
else
{
menuIsVisible = YES;
[self showMenu];
}
}
-(void)hideMenu
{
[UIView animateWithDuration:0.5 animations:^{
// note CGAffineTransforms doesn't use coordinates, they use offset
// so an offset of (0,0) would bring the menuView back to the coordinate
// when it was first instantiated, in our case, (-320, 0).
menuView.transform = CGAffineTransformMakeTranslation(0,0);
} completion:^{
// hide the menu
menuView.alpha = 0;
}];
}
-(void)showMenu
{
// show the menu
menuView.alpha = 1;
[UIView animateWithDuration:0.5 animations:^{
// note CGAffineTransforms doesn't use coordinates, they use offset
// so an offset of (320,0) from coordinate (-320,0) would slide the
// menuView out into view
menuView.transform = CGAffineTransformMakeTranslation(320,0);
}];
}
A Controller like ViewDeck will enable you to do that.
Edit:
I'm not sure what else to add to this, moderator. It's open source code that will add a menu that is controlled by a button which will slide in when clicked and slide out when clicked again, similar to what Facebook and Path have. You're also gaining the touch events with slide.
There's an example of how to use it on the github page here: https://github.com/Inferis/ViewDeck#how-to-use-it and also several examples projects available in the source code.

Resources