I'm using ECSliding and I have this problem!
In my project there are this files:
InitViewController (ECSlidingController)
FirstViewController (UIViewController)
SecondViewController (UIViewController)
LeftMenuViewController (UIViewController)
LeftMenuTwoViewController (UIViewController)
I use InitView to instatiate my FirstView as the topview.
Sliding right shows LeftMenuViewController, that has a button, if pressed change topview to SecondViewController. I would like to know if is it possible to use LeftMenuTwoViewController as the underLeftViewController of SecondView. Also I want a button in LeftMenuTwo that changes topView to FirstView.
I want a FirstView with underLeftViewController as LeftMenuViewController, and SecondView with underLeftViewController as LeftMenuTwoViewController. Each menu have a button that change the topView to the other one with different underLeftViewController.
I did this:
SecondViewController *second = [self.storyboard
instantiateViewControllerWithIdentifier:#"SecondTop"];
[self.slidingViewController anchorTopViewOffScreenTo:ECRight
animations:nil
onComplete:^{
self.slidingViewController.topViewController = second;
[self.slidingViewController resetTopViewWithAnimations:nil
onComplete:^{
LeftMenuTwoViewController *newUnderLeftVC = [self.storyboard
instantiateViewControllerWithIdentifier:#"LeftTwo"];
self.slidingViewController.underLeftViewController = newUnderLeftVC;
}];
}];
But when I push the button the topView starts the bouncing animation by sliding right but never comes back again and immediatly after the TopView goes off screen the underLeftViewController becomes blank. Anyone know why?
Download: My Project
Change the method to this:
-(IBAction)openSecond:(id)sender
{
SecondViewController *second = [self.storyboard instantiateViewControllerWithIdentifier:#"Second"];
ECSlidingViewController *slideController = self.slidingViewController;
[slideController anchorTopViewOffScreenTo:ECRight animations:nil onComplete:^{
slideController.topViewController = second;
[slideController resetTopViewWithAnimations:nil onComplete:^{
LeftMenuTwoViewController *newUnderLeftVC = [self.storyboard instantiateViewControllerWithIdentifier:#"LeftTwo"];
slideController.underLeftViewController = newUnderLeftVC;
}];
}];
}
The problem was that when the view removes itself as the top view controller, calling self.slidingViewController no longer returns a valid instance (it returns nil).
Related
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];
I'm trying to do a switch view. My first view is a storyboard and i want to switch for view2, i have no problem when click the botton in my first view everything is fine. The prolem is when i am trying to go back, the screen is going black and is not going back to the first view. Here the code that i'm using.
ViewController.h
- (IBAction)View2:(id)sender;
ViewController.m
- (IBAction)View2:(id)sender {
View2 *second = [[View2 alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:second animated:YES];
}
And here the code that i am using to go back from the second view to the first.
view2.h
- (IBAction)back:(id)sender;
View2.m
- (IBAction)back:(id)sender {
ViewController *second = [[ViewController2 alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:second animated:YES];
}
Am I doing some kind of error?
Thanks
Your issue is in View2.m
- (IBAction)back:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}
should do the trick
Apple has a View Controller Programming Guide that I suggest skimming through
UPDATE
If you need to jump back more that one ViewController, you should use NSNotificationCenter or keep a reference to the viewController you need to jump back to.
In my experiences, the following line does 1 of 2 things (where self is a subclass of UIViewController)
[self dismissModalViewControllerAnimated:YES];
1) If self has presented another view controller, the line above will dismiss all view controllers that have been presented on top of self
2) If self has not presented any other view controller, the line above will dismiss self back to the previous view controller
I have an App with one MainWindow.xib file. Then I have ViewControllerA.xib and ViewControllerB.xib. My MainWindow.xib have one ViewController that points two ViewControllerA.xib.
On ViewControllerA I have a button and I would like the button, when pressed, to move ViewControllerB onto the screen. How do I do that?
I tried this code, but I think I am missing something:
- (IBAction)btMyButton:(id)sender
{
ViewControllerB * viewController = [[ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:nil];
[[UIApplication sharedApplication].keyWindow addSubview:viewController.view];
[self.navigationController pushViewController:viewController animated:YES];
}
My ViewControllerB does appear, but it is squashed at the top of the screen, over the previous view. Any help is greatly appreciated.
Thank you
Remove the second line:
[[UIApplication sharedApplication].keyWindow addSubview:viewController.view];
You are adding the view twice. The 2nd and 3rd lines both cause the view to be added to the view hierarchy in different places.
--update--
If you remove the 2nd line and are not seeing your view then self.navigationController is most likely nil. Try [self presentModalViewController:] instead.
Make sure that the view of controller B has correct hight you should subtract the navigation bar height 44 px and status bar 20 px as well. Those values are for iPhone.
- (IBAction)btMyButton:(id)sender
{
//you should load from the main app bundle
ViewControllerB * viewController = [[ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:[NSBundle mainBundle]];
// you don't need the following line
//[[UIApplication sharedApplication].keyWindow addSubview:viewController.view];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
}
Update
As the above comment says if you may don't have a navigation controller to push Controller B into. So Add a navigation controller into the main window instead of the view controller and make its root view controller you Controller A.
I hope this helps you,
you will need to remove old viewcontroller from main windows.
- (IBAction)btMyButton:(id)sender
{
//Assuming you declare two Iboutlet controllerA, controllerB mapping with that view as class variable
{
if (self.controllerB == nil)
{
ViewControllerB * viewController = [[ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:nil];
self.controllerB = viewController;
[viewController release];
}
[controllerA.view removeFromSuperview];
[self.view insertSubview:controllerB.view atIndex:0];
}
}
I have a root view controller which has few buttons. On click of these button, I shown up a tab bar controller with each controller showing the table view controller. I have achieved this. So basically, for each table view controller I have a dedicated class. To go ahead, I replaced the tab bar controller, and added the segmented controller to the navigation title view.
The question is how can I set the view based on the selected index. I am able to set the navigation title to be segmented control but on select I am unable to set the view.
Below is what i have achieved so far.
Note: What matters is a running code, I would do that code optimization later on. I dont want to hidde views. I want to call different view controller class.
RootViewController class (on click of the button, i call the first view controller. So that I can set the segment controller:
-(IBAction) pushSegmentController: (id) sender
{
NSLog(#"My Location Button being clicked/touched") ;
FirstViewController *firstViewController = [[FirstViewController alloc] init] ;
[self.navigationController pushViewController:firstViewController animated:YES];
// Releae the view controllers
[firstViewController release];
}
IN FirstViewController class:
-(void)viewDidLoad {
[super viewDidLoad];
NSArray *viewControllers = [self segmentViewControllers];
self.segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Table1", #"Table2"]];
self.navigationItem.titleView = segmentedControl;
[self.segmentedControl addTarget:self
action:#selector(indexDidChangeForSegmentedControl:)
forControlEvents:UIControlEventValueChanged];
self.segmentedControl.selectedSegmentIndex = 0;
}
-(void)indexDidChangeForSegmentedControl:(UISegmentedControl *)aSegmentedControl {
NSUInteger index = aSegmentedControl.selectedSegmentIndex;
if(index ==0) {
UIViewController *table1Controller = [[AustraliaViewController alloc] initWithStyle:UITableViewStylePlain];
**???? HOW SHOULD I SET THE VIEW OVER HERE... AS ITS A PART OF THE NAVIGATION CONTROLLER**
}
else { }
}
Note: I have tried using this option:
[navigationController setViewControllers:theViewControllers animated:NO];
But this option doesnt give me the right result. How should I go ahead with the same as I want to call a view controller class and set its view based on the selected index.
You probably don't want to have one view controller with different views depending on the button index, especially since you already have view controllers for your different screens.
If you want the table view controller to be pushed onto your navigation controller, so it will have a back button that gets you back to FirstViewController, use
-(void)indexDidChangeForSegmentedControl:(UISegmentedControl *)aSegmentedControl {
NSUInteger index = aSegmentedControl.selectedSegmentIndex;
UIViewController *newViewController = nil;
if(index ==0) {
newViewController = [[AustraliaViewController alloc] initWithStyle:UITableViewStylePlain];
} else {
newViewController = [[YourOtherViewController alloc] initWithStyle:UITableViewStylePlain];
}
[self.navigationController pushViewController:newViewController animated:YES];
}
If you'd rather have it slide in from the bottom and you want to handle setting up all necessary user interface (e.g. a dismiss button), replace that last line with
[self presentModalViewController:newViewController animated:YES];
What about?
self.view = table1Controller;
or
[self.view addSubview:table1Controller];
I just saw one more mistake you have done. You are allocating a UIViewController, but initializing it like a tableViewController(with initWithStyle).
If it's a subclass of UITableViewController, alloc it with that, not UIViewController.
I have an app, inside that an UIViewController is attached on the UIWindow.
on the view of UIViewController, i have added a button and a uiview_1 of size 100x80.
this uiview_1 contains another uiview_2 as subview of same size and this uiview_2 contains a UIImageView or a UIlable at runtime (both UIImageView and UIlable are userinteraction enabled)
now on the touch/click of UIImageView, i want to show a new view using presentModalViewController, the problem is the view is shown and using back button on the navigation bar i come to the previous/main screen.
here the problem come in picture, now i am unable to touch the button or the UIImageView.
both are not responding, but app is not crashed and nor frozen.
what is wrong in that?
Plz help in this...
----- EDIT:
Approach First:
SWVController *swvController = [[SWVController alloc] init];
UINavigationController *viewNavController = [[UINavigationController alloc] initWithRootViewController:swvController];
UIViewController *pushController = [[UIViewController alloc] init];
UIWindow *win = [[UIApplication sharedApplication] keyWindow];
[win addSubview:pushController.view];
[pushController presentModalViewController:viewNavController animated:YES];
In the swvController i have back button that calls the dismissModelViewController on click >> result is the Main screen ctrls are not responding to touch – sandy 3 hours ago
Second approach:
SWVController *swvController = [[SWVController alloc] init];
UINavigationController *viewNavController = [[UINavigationController alloc] initWithRootViewController:swvController];
UIViewController *pushController = [[UIViewController alloc] init];
[self addSubview:pushController.view];
[pushController presentModalViewController:viewNavController animated:YES];
In the swvController i have back button that calls the dismissModelViewController on click >> result is the swvController's back button on navbar is not responding – sandy 3 hours ago
3rd approach:
SWVController *swvController = [[SWVController alloc] init];
UINavigationController *viewNavController = [[UINavigationController alloc] initWithRootViewController:swvController];
SampleAppAppDelegate *appdel = [[UIApplication sharedApplication] delegate]; [appdel.viewController presentModalViewController:viewNavController animated:YES];
>> result is working fine, but the problem is i dont want to use SampleAppAppDelegate,i want to give my small Uiview (100x80) as a ctrl to other person , where my ctrl will not able to get the AppDelegate of thet app at run time. – sandy 3 hours ago
Call this method when you want to present the modal view controller:
- (IBAction)showInfo {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
Add this method to your self:
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller {
[self dismissModalViewControllerAnimated:YES];
}
Use a toolbar or other button and connect it to this method in your modal view controller:
- (IBAction)done {
[self.delegate flipsideViewControllerDidFinish:self];
}
All code comes from Apple.
How did you handled click/touch on UIImageView? TouchesBegan/Ended?
Try putting some logs (NSLog) and run your app in debug mode (put some breakpoints) to see if control reaches your action method...
Also, when you do presentModalViewController, you do not need to POP out with back button on navigation bar... you only need to dismissModelViewController to hide it.