I'm new to iOS development and don't get on well with storyboard.
screenshot of storyboard: http://i.stack.imgur.com/s9VTB.png
I have got the push segue working now. But only pushing from the first tableViewController to the second one is animated and pushing back isn't animated.
In the first tableViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"xxx" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"xxx"]) {
// set some properties of segue.destinationViewController
}
}
the second one is not modified.
Update:
I deleted the storyboard, did all of them programmatically and now everything works well.
Sometimes storyboard is just so confusing...
Whether the segue is animated will depend on how you do it. Try:
[self.navigationController popViewControllerAnimated:YES];
Related
I have a problem.
I have a ViewController embed in navigationController.
And use the storyBoard to add the tableView in this viewController.
then,I add the segue.
Finally,I click the cell that the next viewController show twice.
I don't know how to fix it.
Thanks!
This is my code:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 2){
[self performSegueWithIdentifier:#"showAdd" sender:self];
}
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showAdd"]) {
AddCommentViewController *AddCommentVC = segue.destinationViewController;
AddCommentVC.CommentString = _DetailString;
}
}
You have to add the segue between both the UIViewController, not with the cell and UIViewController, as you have connected that segue on click of cell and you are calling the segue manually also that's why it is showing twice.
Do one thing, remove the segue and connect it between UIViewControllers then it will called only once.
I implemented SWRevealController in my application. It has two segues one for slideviewcontroller and viewcontroller.
My slideviewcontroller is UITableViewController, I created a new class MenuTableViewController for use as a custom class of that siderbar(slideview). When I add a MenuTableViewController as a custom class of that view, it isn't shown when i slide a menu. If i leave it blank it's shown.
The problem is that I want when cell clicked to perform segue identifier or a button clicked, but I don't know where to implement them.
You can implement your segue in your tableview's delegate method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"YourSegueIdentifier" sender:self];
}
You can segue to a proper ViewController depending on indexPath of the selected item inside of that method. Then implement your:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"YourSegueIdentifier"])
{
DestinatinoVCClass *destinationVC = (DestinatinoVCClass *)segue.destinationViewController;
//here you can set any public properties of the destinationVC
}
}
But in general, as far implementing SWRevealController into your app goes here is a full tutorial.
With this code every time user click on any cell will perform the segue again and again , I am wondering how could I keep track of the loaded view to keep data when switching views and not an infinite new viewcontroler.
Thanks -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
[self.navigationController
performSegueWithIdentifier:#"rep" sender:self];
} else if (indexPath.row == 1) {
[self.navigationController
performSegueWithIdentifier:#"rep1" sender:self];
}
}
Try my other approach first, but if you really need a maintain a pointer to the new view controller you could try this approach. This should perform the segue once, creating the reference to the view controller which will subsequently be manually pushed into the navigation controller.
Override the view controller methods:
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{
if(self.myViewController == nil){
return YES;
}else{
[self.navigationController pushViewController:self.myViewController animated:YES]
}
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
self.myViewController = (MyViewController*)segue.destinationViewController;
self.myViewController.customVar = 1; //perform initial customization
}
What do I know though, I've never used Storyboards...
Perhaps an alternative to maintaining a reference to the view controller would be to customize the view controller prior to seque.
Override the view controller method:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
MyViewController *targetController = (MyViewController*)segue.destinationViewController;
targetController.customVar = 1;
}
The default implementation of this method does nothing. Your view controller overrides this method when it needs to pass relevant data to the new view controller. The segue object describes the transition and includes references to both view controllers involved in the segue.
You don't need to take new View controller each and every time for each row unless and until you want it customized. This will make large amount of view controllers on storyboard.
So, Just command drag segue from controller A to B. Example: if A is tableViewController and B is simple VC where you are displaying data of table's row then command drag from whole tableViewController to B. Now this will act as common segue with one identifier only.
So in your code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Set your B's label/property etc to cell's data or anything so that it will reflect in B.
B.label = cell.text;
[self performSegueWithIdentifier:#"Identifier" sender:self];
}
Hope this helps.
I think you can keep the new viewController's pointer. Then next time you can use it like this:
[self.navigationController pushViewController:thePointer animated:YES]
I very seldom use Storyboard. So I am not sure it will work.
I am getting this error when I try to preform a segue...
2012-11-14 20:24:54.133 MyApp[26266:c07] nested push animation can result in corrupted navigation bar
2012-11-14 20:24:54.486 MyApp[26266:c07] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
2012-11-14 20:24:54.487 MyApp[26266:c07] Unbalanced calls to begin/end appearance transitions for <SheetDrillDownViewController: 0xa1bb980>.
Here is my setup: Initial view --> next view (UITableView) --> last view (UITable)
Each cell pushes to another view until the last view. I do not have a modal segue, i have a push segue... I have the push segues linked from the cell to the next view, each with different names... I have a perform segue line in my selectedRowAtIndex method. I have tried removing that method, with people saying I am double calling the segue, but then the cell when clicked turns blue, and doesn't push to anywhere... How can I fix this error? Thanks.
Here is my code:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath) {
[self performSegueWithIdentifier:#"subjectDrillDown" sender:nil];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Attempting to identify segue...");
// Make sure we're referring to the correct segue
if ([[segue identifier] isEqualToString:#"subjectDrillDown"]) {
NSLog(#"Segue has been identified...");
// Get reference to the destination view controller
SubjectDrillDownViewController *vc = [segue destinationViewController];
NSInteger selectedIndex = [[self.tableView indexPathForSelectedRow] row];
NSMutableDictionary *object = [tableDataSource objectAtIndex:selectedIndex];
NSString *key = [object valueForKey:#"key"];
[vc setSelectedItem:key];
NSLog(#"Switching to %# detail view...",key);
NSLog(#"Passing dictionary to %# view... (Source below)\n\n %#",key,[NSString stringWithFormat:#"%#", [tableDataSource objectAtIndex:selectedIndex]]);
[vc setDetailDataSourceDict:[tableDataSource objectAtIndex:selectedIndex]];
}
else {
NSLog(#"ERROR, DOUBLE CHECK SEGUE'S NAME!");
}
}
I have seen all of the other Stack Overflow questions, but most of the correct answers don't work for me...
EDIT:
The next view is able to load, but when I click the back button, there are suddenly two more views...
UPDATE:
I will try to post the number of times Attempting to identify segue... NSLogs, but my compiler suddenly won't run :(
You surely don't need to perform segue in didSelectRowAtIndexPath, if you have already configured it like cell -> next view.
But, removing the call from there doesn't work for you then you can try the segue from view controller (ctrl+drag from view area) to next view and keep the segue call in didSelectRowAtIndexPath
I always use one of the following methods
Method 1:
Segue from UITableViewCell to Next View Controller
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Nothing
}
Method 2:
Segue from Main View Controller to Next View Controller
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"subjectDrillDown" sender:nil];
}
The error you are getting is because you have segue and you perform the segue manually when selected - hence, it is resulting in nested push animation
Make sure the name of the segue is correct and you are using ONLY one of the above methods
This is my first iPad/Storyboard/SplitViewController and it has a table as the master and each row is a separate document for the detail view. I am starting from the Xcode 4.2 template.
I have gotten the iPhone half to work. I hooked up a segue from the tableviewcell and get the call:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
And with that I can bring up the detail view correctly.
On the iPad storyboard, I don't get the prepareforsegue call. I have tried creating a segue between the masterviewcontroller and then tried the tableviewcell controls but can't get it to call my prepareforsegue.
I also tried:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"segueDetailIpad" sender:nil];
}
That will call my Segue, but the tableview doesn't have an indexPath set. (It is set on the iPhone though).
Also, when I switchback to the iPhone version, it wants to call the same performseguewithidentifier (as above), but then I have to switch between different #"segueDetailIpad" parameters.
It seems to me I am mixing "old" and "new" models and need to find some way to
get the iPad to use the segue and not rely on the didSelectRowAtIndexPath.
Hope this is enough for some suggestions ;-)
thx!
Just as user589310 said I was able to solve my similar problem by embedding the [segue destinationViewController] in a UINavigationController.
For example:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue destinationViewController] class] == [UINavigationController class])
{
[[[[segue destinationViewController] viewControllers] objectAtIndex:0] setDelegate:self];
}
else
[[segue destinationViewController] setDelegate:self];
}