how to make animation before a segue - iphone

I looked for a few articles on SO and on other sources, but can't find answer. This question will be a complex one. First, what i have: two view controllers (let's call them VC1 and VC2), and two buttons for one on each VC (let's call them in the same way as B1 and B2).
Here is image
When app start, B1 slide from right border of screen to middle position like on screenshot;
I'll add code of this below. I want make this: when I click on B1, B1 slide left behind the border of the screen, segue is performed and then B2 button slide from right to centre(like B! button does). How can I make this? I must do this in custom segue class, or in some UIView method?
And on more question, if we click B1 (it slides beyond the left border), we at the VC2. If I click back button (bottom button on screenshot), I'll see white screen (because B1 have center coordinates about - 100). How i can prevent this too?
VC1 code
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIButton *buttonOne;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CGPoint startPossitionForButton = CGPointMake(345, 220);
self.buttonOne.center = startPossitionForButton;
[self slideButton];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[self slideButtonOffScreen];
}
-(void)slideButton
{
[UIView animateWithDuration:0.3 animations:^{
CGPoint endPossitionForButton = CGPointMake(155, 220);
self.buttonOne.center = endPossitionForButton;
}];
}
-(void)slideButtonOffScreen
{
[UIView animateWithDuration:0.3 animations:^{
CGPoint endPossitionForButton = CGPointMake(-100, 220);
self.buttonOne.center = endPossitionForButton;
}];
}
VC2 code
#interface VC2 ()
#property (weak, nonatomic) IBOutlet UIButton *backButton;
#property (weak, nonatomic) IBOutlet UIButton *buttonTwo;
#end
#implementation VC2
- (IBAction)back:(id)sender {
[self.navigationController popViewControllerAnimated:NO];
}
-(void)slideButton
{
[UIView animateWithDuration:0.3 animations:^{
CGPoint endPossitionForButton = CGPointMake(155, 220);
self.buttonTwo.center = endPossitionForButton;
}];
}
- (void)viewDidLoad
{
[super viewDidLoad];
CGPoint startPossitionForButton = CGPointMake(345, 220);
self.buttonTwo.center = startPossitionForButton;
[self slideButton];
}
Custom Segue class:
-(void)perform
{
UIViewController *src = (UIViewController *) self.sourceViewController;
UIViewController *dst = (UIViewController *) self.destinationViewController;
[src.navigationController pushViewController:dst animated:NO];
}
Any help will be useful

Instead of calling the segue when pressing B1 call a helper action method. Inside this method perform the sliding and call the segue using performSegueWithIdentifier.
To slide the button back check its position in viewWillAppear and move it back if necessary.

Related

ECSlidingViewController How to go from one TopViewController to another TopViewController using animation in iOS

I am using ECSlidingViewController in my app for Facebook style swipe effect. I have 2 TopViewControllers, one left and one right side view controller and one initviewcontroller which is a slidingviewcontroller subclass.
1. InitViewController:ECSlidingViewController
2.MainViewController (TopViewController)
3.LeftMenuViewContrller (UIViewController)
4.RightMenuViewController (UIViewController)
5.DetailViewController (TopViewController)
I have tableview on my MainViewController which contains the calendar events. The problem is that I want to go to MainViewController to DetailViewController by clicking the event in tableView:didSelectRowAtIndexPath: methods to show the events details which is another topview controller with some animation( which I am unable to get so far). I am using following code which is getting me to the DetailViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailsViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"details"];
self.slidingViewController.topViewController = newTopViewController;
[self.slidingViewController resetTopView];
}
this is my viewDidLoad method
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.layer.shadowOpacity = 0.75f;
self.view.layer.shadowRadius = 10.0f;
self.view.layer.shadowColor = [UIColor blackColor].CGColor;
if (![self.slidingViewController.underLeftViewController isKindOfClass:[LeftViewController class]]) {
self.slidingViewController.underLeftViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Left"];
}
if (![self.slidingViewController.underRightViewController isKindOfClass:[RightViewController class]]) {
self.slidingViewController.underRightViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Right"];
}
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
}
I want to get the animation like the UINavigationController or Modal style
[self.navigationController pushViewController:newTopViewController animated:YES];
or
[self presentViewController:newTopViewController animated:YES completion:nil];
please help. thank you.
Are you using Storyboard? Could you perform a Segue? In the storyboard setup the name and the link and style as Modal along with the Transition.
In your DidSelectRowAtIndex put this
[self performSegueWithIdentifier:#"eventDetail" sender:#(indexPath.row)];
Then declare this method
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"eventDetail"])
{
DetailsViewController *destViewController = segue.destinationViewController;
destViewController.eventRow = sender;
}
// You can test for other Segue names here
}
Then in the DetailsViewController.h put
// Allows sending View Controller to give this controller data
#property (nonatomic, strong) int *eventRow;
And in the .m put
#synthesize eventRow;
Now in your DetailsViewController it should animate to it and the sliding will be disabled (unless you declare all the ECS bits as normal). You also have an Int eventRow which tells you which cell was clicked.
You can create a back button and do this;
[self dismissViewControllerAnimated:YES completion:nil];
EDIT
OR you could try this but I am not sure if it will animate plus you need to figure out how to pass stuff, maybe a combination of the two...
UIViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"eventDetail"];
CGRect frame = self.slidingViewController.topViewController.view.frame;
self.slidingViewController.topViewController = newTopViewController;
self.slidingViewController.topViewController.view.frame = frame;
[self.slidingViewController resetTopView];

how to load uiview from nib

I am trying to change views when I swipe. I have the swipe working find as I have tested this by changing the background color.
Since then however I have added a new view.nib and set the class to be the same as the current view.
Inside this classes .h file I have done this
#interface MasterViewController : UIViewController <UIGestureRecognizerDelegate>{
UIView *myView;
UIView *secondView;
}
#property (strong, nonatomic) IBOutlet UIView *myView; // attached to Viewcontroller nib
#property (strong, nonatomic) IBOutlet UIView *secondView; // attached to the secondView
- (void)swipedScreen;
MyView is the main view that appears first, secondView is the view of the nib that I have created and changed its class to relate to this view.
From there I have done this in the .m file
- (void) setupSwipeGestureRecognizer {
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipedScreen)];
swipeGesture.direction = (UISwipeGestureRecognizerDirectionRight|UISwipeGestureRecognizerDirectionLeft);
[myView addGestureRecognizer:swipeGesture];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title = #"Prototype";
[self setupSwipeGestureRecognizer];
}
- (void)swipedScreen
{
// Not sure what to do here.
[[NSBundle mainBundle] loadNibNamed:#"SecondView" owner:self options:nil];
}
I just dont know what to do in swipedScreen method to get the secondView to appear.. I would like to animate this view to slid in from the right.. but at the moment that comes secondary to actually just getting the view to appear... not sure what I am doing wrong here but obviously its something quite fundamental.
any help would be greatly appreciated.
As I commented:
- (void)swipedScreen
{
[UIView animateWithDuration:3.0f delay:0 options:UIViewAnimationOptionCurveLinear
animations:^{
secondView.frame = CGRectMake(180, secondView.frame.origin.y, secondView.frame.size.width, secondView.frame.size.height);
}
completion:^(BOOL finished){
myView.hidden = YES;
}];
}
Actually, you'll have to change the X, Y, Width and height values as you want to animate, and when it's completed, I set the main view - myView - hidden.

How do I create a sizeable subView

I'm looking to create a sizeable subview that's draggable like this:
If there is an IBAction that takes you to the next View (SecondViewController) and when it does, there's another IBAction there and when you click on that one, it creates a SubView that's about half of the size of the current screen you're in (SecondViewController) that shows the third view controller that would be created? Also, how would you make that subView draggable? Thank you for helping.
Sorry, just to be clear, you want your second view controller to have a button that when tapped, adds your third view controller taking up half the screen at the bottom?
If this is the case then you can do this with the new view controller containers in iOS5.
Ok, so you have three view controllers. For the sake of this lets say your class are called FirstViewController, SecondViewController and ThirdViewController.
I assume from what you say that you already have you instance of FirstViewController with a button, that moves you on to an instance of SecondViewController, and that the issue is then getting SecondViewController to add an instance of ThirdViewController to the bottom half of the screen when a button is pressed.
The .m file for SecondViewController will need to do something like this:
#import "ThirdViewController.h"
#interface SecondViewController ()
#property (retain) ThirdViewController *thirdViewConroller;
- (void)buttonTap;
#end
#implementation SecondViewController
#synthesize thirdViewConroller = _thirdViewConroller;
- (void)dealloc {
self.thirdViewConroller = nil;
[super dealloc];
}
- (void)loadView {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.titleLabel.text = #"Show third controller";
[button addTarget:self action:#selector(buttonTap) forControlEvents:UIControlEventTouchUpInside];
button.frame = // Some CGRect of where you want the button to be
[self.view addSubview:button];
}
- (void)buttonTap {
// When the button is tapped, create an instance of your ThirdViewController and add it
self.thirdViewConroller = [[ThirdViewController alloc] initWithFrame:/* Some CGRect where you want the controller to be */ ];
[self.thirdViewConroller willMoveToParentViewController:self];
[self addChildViewController:self.thirdViewConroller];
[self.thirdViewConroller didMoveToParentViewController:self];
}
#end
This should give you a button on your second controller, that will create and add you third controller. Make sure yo us till have all the standard methods that you had before, this should be in addition to what you have.
In your interface for ThirdViewController:
#interface ThirdViewController : UIViewController <NSObject>
- (id)initWithFrame:(CGRect)frame;
#end
Then in the implementation of your ThirdViewController:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithNibName:nil bundle:nil];
if (self) {
self.view.frame = frame;
// Do your init stuff here
}
return self;
}
It should then handle adding the views and such forth.
Make sure your thirdViewController class has a valid initWithFrame: initialiser method.
This should do the trick, if you need any further help let me know :)

how to pass touchesBegan from UIScrollView to UIViewController

Actually, I want to push data from one view to other. I have a UIScrollView which has images on top of it. Now I want to push the data from that view to other view since whenever I do touch on that image view I want to select the position and push the location to other view.
UIScrollView does not have navigationController and cannot be able to push it.
UIScrollView is on top of UIViewController class. Is there a way to send the UITouch from UIScrollView to UIViewController Class and let that class push the view or do I have to work around some thing.
I have the following code for UIScrollView class,
ImageScrollView.m
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *t = [touches anyObject];
CGPoint touchInScrollView = [t locationInView:imageView];
NSLog(#"x: %f", floor(touchInScrollView.x));
NSLog(#"Y : %f", floor(touchInScrollView.y));
/****Cant be done since pushViewController is not allowed in UIScrollView.****/
DetailViewController *newView = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
[self.navigationController pushViewController:newView animated:YES];
}
Add this property to ImageScrollView.h
#property (nonatomic, retain) IBOutlet UIViewController* parentVC;
Add this line after #implementation in ImageScrollView.m
#synthesize parentVC;
Add this line to your - (void)dealloc method in ImageScrollView.m
[parentVC release];
If you create your ImageScrollView programmatically, after creation in your view controller:
imageScrollViewYouJustMade.parentVC = self;
If you create your ImageScrollView in Interface Builder, connect the parentVC outlet to File's Owner.
To push a new view controller, in ImageScrollView.m
[self.parentVC.navigationController pushViewController:newView animated:YES];
Here's an alternative,
I can't say for sure without knowing more about your application, but in general if I had a scroll view containing images that I wanted to tap, I would use a UIButton instead of UIImageView, and do something like
btnImage = [UIImage imageNamed:#"image.png"];
[btn setImage:btnImage forState:UIControlStateNormal];
If you aren't creating buttons programmatically, you can also set an image as it's background by changing the Type in the Attributes inspector to Custom, and change the Background attribute to the desired image.
Using a button instead of an image view will allow you to connect the touchDown outlet of the button to an IBAction method in your primary view controller that might look like:
- (IBAction)smileyFaceButtonTapped:(UIButton*)sender;

Iphone - Calling animations to a view from another class than the viewController

Two really quick questions, I searched the web but couldn't find answers..
Is there any way to call block animations to a view from a class that is different from the viewController of that view. I also couldn't figure out how to add a subview to that view in a method that exists in a different class than the viewController ( the only way I can do it is [self.view addSubview:xxxxx]; in the viewController for my view)
Any help would be greatly appreciated and helpful.
Thank you!!
Keep a reference to YourViewController instance on ApplicationDelegate, and modify its subviews in OtherClass.
//in ApplicationDelegate.h
#property (strong, nonatomic) YourViewController *ref;
//in ApplicationDelegate.m
#synthesize ref;
self.ref = [[YourViewController alloc] initWithNibName:nil bundle:nil];
//in YourViewController.h
#property (retain, nonatomic) UIImageView *myImageView;
//in YourViewController.m
#synthesize myImageView;
//in OtherClass.m
[UIView animateWithDuration:DURATION delay:DELAY
options:OPTION
animations:^(void)
{
[[UIApplication sharedApplication] delegate].ref.myImageView.center=CGPointMake(100,100);
}
completion:^(BOOL finished)
{
[[UIApplication sharedApplication] delegate].ref.myImageView.center=CGPointMake(200,200);
}];
Well if the view that you're calling on the animation on also has a view controller then what you could do is create a method in that view controller that makes that animation. then in the other view that you want to call that animation you could do
[otherViewController animationMethod];
Honestly that's the best i can think of.