ViewController issue in Xcode? - objective-c

I am fairly new to Xcode, but I have run into a bit of a problem. I have a tabbed view controller, and one subtab has a UITableView. On cell click, I need TableData (a ViewController) to open up. For some reason, I just get a black screen. I then changed my code to this:
TableData *newView = [self.storyboard instantiateViewControllerWithIdentifier:#"TableData"];
[self presentViewController:newView animated:YES completion:nil];
but I get an error SIGABRT in Xcode. How do I fix this?
This works, but gives me a black screen:
TableData *view = [TableData alloc];
view.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController: view animated:YES];

Just create an identifier for the segue inside the storyboard and then use:
[self performSegueWithIdentifier:#"yourTableViewStoryboardSegueIdentifier" sender:self];
UPDATE:
Problem was most likely due to user grabbing an invalid row from his tableView. In order to just grab the row number all you need to do is:
int rowNumberSelected = indexPath.row;
As for his second code snippet, the reason its only showing a black screen is because he is not actually linking it to his viewController in the storyboard. He is simply just allocating the code. If he added subviews through the code, then they would show up but nothing from the storyboard.
Since the user is using Storyboard, its always better to just use segues and dismissals however.

Related

Cocoa Touch: How can I update the table view everytime I tap on a tab of tabbar?

I'm using iOS 8 and Objective c.
If I do a change in the values in one view, I can't see the reflection on my other tabviews. But if I re-run the app, I can see the reflection on the other tabs. Sometimes it works, sometimes it doesn't. How can I make sure that when I tap on a tabview, it will be reload according to the database?
I'm not sure what you are trying in your code, but you can try to implement the viewDidAppear method with a reloadData in your tableView:
- (void)viewDidAppear:(BOOL)animated{
[self.tableView reloadData];
}
[tableView reloadData] is the one you are looking for , this UITableView method refreshes the table view by calling its delegate and data source methods again to get fresh data.
I solved it!
Here is my code:
"TheMaster" is the main tabview. Here selectedIndex can be 0,1,2.... according to the placement of the tab. The leftmost tab has the index 0, and after that 1,2, and so on.
UITabBarController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"TheMaster"];
controller.selectedIndex=0;
[self presentViewController:controller animated:YES completion:nil ];

iOS7 - popToRootViewControllerAnimated not doing anything

I have looked around but haven't found a satisfying answer. My problem is that whenever I call popToRootViewControllerAnimated:(BOOL) it is not doing anything. When I NSLog it, it logs (null).
Let me back up a bit here. I have a table view controller that has a list of things, at the navigation bar up top there is an option to add and that takes me to a new view controller with a segue "Present as PopOver" which gets rid of the principal or main navigation bar. So I made one manually and added 2 bar button items "Cancel" and "Add". When "Cancel" is tapped, it should take the user back to the table view controller and discard changes, when "Add" button is tapped, it should also take user back to the previous table view controller with the changes. But it's not doing anything.
Here is my code.
- (IBAction)cancelButton:(UIBarButtonItem *)sender {
UINavigationController * navigationController = self.navigationController;
NSLog(#"%#", navigationController);
NSLog(#"cancel tapped though");
ListingTableViewController *rootController = [[ListingTableViewController alloc] init];
[navigationController popToRootViewControllerAnimated:NO];
[navigationController pushViewController:rootController animated:YES];
}
As far as the segue, this view controller is not connected to anything, or should I connect it? This is a noobish question indeed. Here is my xcode screenshot.
Check this link for the screenshot of the storyboard
http://i.stack.imgur.com/lqnCF.png
You must call
- (IBAction)cancelButton:(UIBarButtonItem *)sender {
NSLog(#"cancel tapped though");
[self dismissViewControllerAnimated:YES completion:nil];
}
instead of popToRootViewControllerAnimated because your VC presented and not pushed!
When presenting a view, you are not pushing it in your navigation controller, but having it presented. To dismiss it, try using [self.presentingViewController dismissViewControllerAnimated:NO completion:nil].

presentViewController over TabBarController causes "attempt to present *VC on TabBarVC whose view is not in the window hierarchy"

My root view controller is a Tab Bar Controller loaded in the delegate. Each of the tabs is a table view controller. When the application is first loaded I want a login screen to popup via presentViewController, which I have in my viewDidLoad method of the Tab Bar Controller. It results in the window hierarchy error that I have read about - though none of the solutions have worked for me. I tried instead presenting the modal view in the viewDidLoad method of the first tab but this resulted in the same error.
In my tab bar view controller in viewDidLoad, my code is:
CLLoginViewController *loginVC = [[CLLoginViewController alloc] init];
loginVC.delegate = self;
[self.view addSubview:loginVC.view];
[self presentViewController:loginVC animated:NO completion:nil];
Your question is quite vague but what i have understood, You want to present a login screen before the tabController is loaded.
So a better way would be, In your AppDelegate when setting rootViewController of window, do something like this
if([[NSUserDefaults standardUserDefaults] boolForKey:#"showTabBar"]){
self.window.rootViewController = tabBarControllerObject; //TabBarView is loaded
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"showTabBar"];
}
else{
self.window.rootViewController = tabBarControllerObject; //Login Screen is loaded for first time.
}
Hope this helps

Superview is Nil after Second Launch of View Controller

I've spent hours and I cant figure this out. I have a detail view controller (UITableView) which is launched here:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
EventLocationDetailController *newDetailViewController = [[EventLocationDetailController alloc] initWithNibName:#"EventLocationDetailController" bundle:nil];
self.eventDetailController = newDetailViewController;
[self.navigationController pushViewController:self.eventDetailController animated:YES];
[newDetailViewController release];
}
In the detail view controller there is a button method which calls the below method to display a slide-in-slide-out animation confirming the users choice:
-(void)confirmLastActionWithMessage:(NSString *)message {
ConfirmActionViewController *newConfirmActionViewController = [[ConfirmActionViewController alloc] initWithNibName:#"ConfirmActionViewController" bundle:nil];
self.confirmActionViewController = newConfirmActionViewController;
[newConfirmActionViewController release];
[[self.view superview] addSubview:self.confirmActionViewController.view];
}
Protocol method called by the ConfirmActionViewController indicating that the animation is finished.
-(void)didFinishConfirmDisplay:(UIView *)viewToRemoveFromSuperview {
[viewToRemoveFromSuperview removeFromSuperview];
}
This works perfect the first time I press the button. If I pop the detail controller and push it back on to the stack and press the button again, nothing happens and the detail controller's superview is nil every time I invoke the method after that. Superview is not nil in the viewWillAppear method for the detail view, only when It gets to the confirmLastActionWithMessage method. No other user interaction happens in between. How do I get the superview back? I have a similar code that works without animation.
I've also noticed that the detail view controller hasn't called dealloc when popped off the stack. Not sure where the problem is.
Thanks.
EDIT 1
OK. I replaced the addSubview line with this one:
[self.view insertSubview:self.confirmActionViewController.view atIndex:0];
and the animation view appeared underneath one of the table cells. Could one of the table cells steal the superview?
Well I don't really understand why you should add the subview to the superview. Why not add it just to self.view
I may not be able to explain why there is no superview but try either adding the controller view to self.view or
[[[[UIApplication sharedApplication] delegate] window] addSubview:yourview];
This will render the view on top of everything.

Navigating back to main ViewController dismissViewControllerAnimated dilemma

I have 2 ViewControllers directly connected with a push segue. I am navigating from first to second view controller by calling [self performSegueWithIdentifier:#"segueIdentifier" sender:sender]. On the second one I have an IBAction method that is bound to a "Done" button. Pressing that button should basically cause the first view controller to be displayed (sort of a back button). I managed to do that with:
NSArray *viewControllers = self.navigationController.viewControllers;
[self.navigationController popToViewController:[viewControllers
objectAtIndex:0] animated:YES];
I did try to achieve the same effect by using:
[self dismissViewControllerAnimated:YES completion:nil];
No matter what I tried though this didn't do the job. I am trying to understand what exactly am I missing but I can't figure it out. Does dismissViewControllerAnimated method work only with Modal segues ( this is the only thing that came to mind ).
Thank you
Yes,
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
is when a UIViewController is displayed modally.
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
should do what you are seeking.
So basically, in your second VC:
[self.navigationController popViewControllerAnimated:YES];
You will save you a lot of trouble if you read the UIViewController and UINavigationController references. Twice ;)