I have a Storyboard which loads a XIB with a TableView inside.
When the user selects a row from the TableView a new XIB should be loaded with the following method pushViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
[tableView deselectRowAtIndexPath:indexPath animated:YES];
RecipeDetailViewController *recipeDetailViewController = [[RecipeDetailViewController alloc] init];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *str = cell.textLabel.text;
recipeDetailViewController.navTitle = str;
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:recipeDetailViewController animated:YES];
}
The loaded new XIB should show the following View (with a button inside):
Instead it loads a black view like below:
I checked whether the view is connected to the viewcontroller. From my point of view everything is fine. In IB it the view is connected the File's Owner:
I solved it. All I had to do is to close XCode and reopen the project. After that all worked just fine!
Related
I'm creating a table view application.
I have to display a web view when a cell in the table view is touched.
But the tableView's navigation controller is showing a nil value.
And it is not pushing to the detailsViewController.
Anyone please help me to resolve this issue.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NewsDetailsViewController *detailsVc=[[NewsDetailsViewController alloc]initWithNibName:#"NewsDetailsViewController" bundle:nil];
NSString *launchURL = [nf.newsStories [indexPath.row] objectForKey:#"link"];
detailsVc.url = launchURL;
NSLog(#"View controllers before pushing : %#",self.navigationController.viewControllers);
[self.navigationController pushViewController:detailsVc animated:YES];
NSLog(#"View controllers after pushing : %#",self.navigationController.viewControllers);
}
NavigationController Value in debugger
I guess the problem is with creating your controller which this line
NewsDetailsViewController *detailsVc=[[NewsDetailsViewController alloc]initWithNibName:#"NewsDetailsViewController" bundle:nil];
Try to replace it with this one
NewsDetailsViewController *detailsVc= [[NSBundle mainBundle] loadNibNamed:#"NewsDetailsViewController"
owner:self
options:nil][0];
Anyway I advise you to move to using Storyboards and Segues
I am working in a table view app using story board . I want to perform event on selection
of cell in table view . So when I select a cell element , a next view(detailview) should be
open for displaying further details .
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.dv = [[Detail alloc]initWithNibName:#"Detail" bundle:nil];
dv.dic = [self.arr1 objectAtIndex:indexPath.row];
[self.view addSubview:dv.view];
}
Instead try this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.dv = [[Detail alloc]initWithNibName:#"Detail" bundle:nil];
dv.dic = [self.arr1 objectAtIndex:indexPath.row];
[self presentViewController:dv animated:YES completion:nil];
}
And if you want to dismiss use this code:
[self dismissViewControllerAnimated:YES completion:nil];
You should use a navigation controller and when selecting a row, push the detail view into it.
To create navigation controller: selected the tableview controller and go Editor / Embed in / Navigation Controller.
Then do:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// dv = [Detail alloc] initWithNibName:#"Detail" bundle:nil];
dv = [storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
dv.dic = [self.arr1 objectAtIndex:indexPath.row];
[self.navigationController pushViewController:dv];
}
The commented line is if you're not using storyboard.
Or you can do as Abdullah suggested, but implement a dismiss button with
[self dismissViewControllerAnimated:YES completion:nil];
In the storyboard drag a segue from the viewcontroller icon at the bottom of your view to the next viewcontroller you want to segue to. Make sure that your view is embedded in a navigation controller. Press the arrow that appears between your tableviewcontroller and the target view controller and make sure you label it with a segue identifier. Then in the method you are describing make sure they selected the correct index path with an if statement and write
[self performSegueWithIdentifier:#"theNameOfYourIdentifierFromTheStoryboard"];
That being said, I think that there is a large body of information you should research.
Read this: http://www.appcoda.com/use-storyboards-to-build-navigation-controller-and-table-view/ as a start.
I'm developing an Ipad app with a custom split view. In the master view I have a tableViewController. I add items in this one with an add button in the navigation bar. This button is linked (i work with storyboard) with a popover segue to an other tableViewController that contains a few cells to enter datas. A button “save” dismiss the popover view an add item in the list of the masterView. What I want to do next is link master view’s prototype cells to an other view to enable the user to edit the selected item. I want to link this view with a popover segue (just like with the add button) and there‘s where is the problème : I get an red issue from xcode : Couldn't compile connection: => anchorView => > .
This a sample of my code that works fine. I would like to do pretty the same when I tap on a cell for editing.
The masterSplitView table
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"assetCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Configure the cell...
AssetModel *myAssetModel = [self.arrayAsset objectAtIndex:indexPath.row];
cell.textLabel.text = myAssetModel.name;
// cell.textLabel.text = #"test";
return cell;
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"addAssetSegue"]){
AddAssetTVC *addAssetTVC = segue.destinationViewController;
addAssetTVC.delegate = self;
UIStoryboardPopoverSegue* popoverSegue = (UIStoryboardPopoverSegue*)segue;
[addAssetTVC setPopoverController:[popoverSegue popoverController]];
}
}
- (void) theSaveButtonOnTheAddAssetTVCWasTapped:(AddAssetTVC *)controller{
[controller.navigationController popViewControllerAnimated:YES];
[self reloadCache];
[self.tableView reloadData];
[self viewDidLoad];
}
And the save method of the add view :
- (IBAction)save:(id)sender{
[popoverController dismissPopoverAnimated:YES];
NSLog(#"Telling the ADDASSET Delegate that Save was tapped on the AddAssetTVC");
{...unrevelant coredata methods}
[self.delegate theSaveButtonOnTheAddAssetTVCWasTapped:self];
}
Thanks you for reading,
Alexandre
I had the same problem. Solved it by using a custom segue. In the class's prepare method:
Grab the source view controller which is either a custom controller or a UITableViewController
Grab the destination controller
Create a UIPopoverController initialized with the destination controller
Get the cell of the currently selected row
Store the popover as a property on the destination controller (that way you can dismiss it and it will not be deallocated)
Present the popover using the cell's frame as the CGRect
Set the size of the popover because it will be max sized otherwise
Here's some sample code:
UITableViewController *tvc = (UITableViewController *)self.sourceViewController;
DetailsViewController *details = (DetailsViewController *)self.destinationViewController;
UITableViewCell *cell = [tvc.tableView cellForRowAtIndexPath:[tvc.tableView indexPathForSelectedRow]];
UIPopoverController *pop = [[UIPopoverController alloc] initWithContentViewController:details];
details.popoverController = pop;
CGSize size = CGSizeMake(640, 460);
pop.popoverContentSize = size;
[pop presentPopoverFromRect:cell.frame
inView:tvc.tableView
permittedArrowDirections:UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown
animated:YES];
I have been able to do this with minimal coding. Try this:
I added a button to my Toolbar or Nav Bar. This is a dummy button that will be the Anchor for your Popover. Disable the button (uncheck Enable). You use the same button for multiple tableviews. I use the Organizer icon image in the button to simulate drill down, or you can set a custom image or title for each in the didSelectRowAtIndex method before calling performSegueWithIdentifier... Explained later...
Then connect the button to your Popover view. Obviously set the type to Popover
Tap the Segue arrow and name the Segue, for this example: "SegToDetail".
Now in the Master / Parent code with the tableview add the method, didSelectRowAtIndex... In that method you can set what the button looks. Most importantly you call: [self performSegueWithIdentifier:#"SegToDetail"... And thats it...
Now you can pass any information in the prepareForSegue methods as in any segue transition.
Based on #Rich's answer but with PopoverPresentationController and in Swift.
override func perform() {
let svc = self.sourceViewController as! yourSourceViewController
let pvc = self.destinationViewController as! yourPresentedViewController
// Present the view controller using the popover style
pvc.modalPresentationStyle = UIModalPresentationStyle.Popover
svc.presentViewController(pvc, animated: true, completion: nil)
// Get the popover presentation controller and configure it
let cell = svc.tableView.cellForRowAtIndexPath(svc.tableView.indexPathForSelectedRow!)
let presentationController = pvc.popoverPresentationController
presentationController!.permittedArrowDirections = .Any
presentationController!.sourceView = svc.tableView
presentationController!.sourceRect = cell!.frame
}
I have a UITableView which is added to a view as a subview. When selecting a row a new view will be present with pushViewController: and the user has the option to push a Back-button to go back to the UITableView but then the cell is still selected.
Is there a way to deselect this when the view appears?
I have read that I should use the following code but I can't get it working. No errors, no warnings, no nothing.
[tableProgram deselectRowAtIndexPath:[tableProgram indexPathForSelectedRow] animated:NO];
You should deselect the row in the didSelectRowAtIndextPath method of the delegate of your UITableView. It should look something like this.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
/* initialize your view controller here v and then push it */
SomeViewController *v = [[[SomeViewController alloc] init] autorelease];
[self.navigationController pushViewController:v animated:YES];
}
Dot confuse it with didDeselectRowAtIndextPath method - it happens as people do not pay much attention when selecting methods from intelisense.
Another place you can use this is inside viewDidAppear
- (void)viewDidAppear:(BOOL)animated
and insert the following
NSIndexPath *indexPath = [tableView indexPathForSelectedRow];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
The cell stays selected after clicked and pushed to a different view controller, but deselects when it pops back to the original view controller, so it gives the user a visual cue for the last selected row.
quote SimonBS:
tried that and hoped it would work (to
get the animation) but it seems that
both viewDidAppear:(BOOL)animated and
viewWillAppear:(BOOL)animated aren't
called when in a subview.
the code by honcheng does work
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSIndexPath *indexPath = [self.tableViewOutlet indexPathForSelectedRow];
[self.tableViewOutlet deselectRowAtIndexPath:indexPath animated:YES];
}
you just need to use it on the TableView's superview. (For instance: if you have a xib file with a TableView subview inside the view you just need to go to the corresponding view controller code and override viewWillAppear, i just did it and it works! hello visual cue!)
I am doing a book kinda application using a viewBased application. The mainView acts as the backgroundView for loading pages. Each page is a different view and have its own nib. When i swipe on a page(actually on the mainView which have loaded the current view/page), that page will be removed and the next/previous page will be added.
[currentPage.view removeFromSuperview];
[self.view insertSubview:nextPage.view atIndex:0];
I have added a popoverController with a barbutton in this mainView. Its intialized with a tableviewController class named popClass. PopClass is another UITableViewController class which will act as the parent for the popViewController.
self.myPopController = [[PopController alloc] initWithStyle:UITableViewStylePlain];
self.myPopOverController = [[UIPopoverController alloc] initWithContentViewController:myPopController];
When I select certain row in the popover, I want the backgroundview(mainView) to load the page corresponding to the number of the row.
For that I have written a function in bookView(mainView) Controller class. And is calling it from the popOver's parent class when i select certain row.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger toPageNumber = indexPath.row + 1;
[viewController changeToPage:toPageNumber];
}
Function and the lines of code are executing but nothing is happening. Even the log lines are printed but no action takes place. The code is the same for removing a page and adding another page which is working successfully when i swipe the view/page.
What is the problem? OR is there anyother way to make the view change in mainView by using the popover?
You need to have refernce of the background view controller in the popover controller.
In the PopController controller you should have a delagate like:
#interface PopController: UITablViewController{
//// other varibales;
id delegate;
}
#property (nonatomic, retain) id delgate;
Now from the class in which you are showing the popovercontroller
you should add this line:
[myPopController setDelegate:self];
Then you can easily acces any method of the main view controller class. By using
[delegate callTheRequiredMethod];
Hope this helps.
Thanks,
Madhup
It's hard to tell what's going wrong without looking at the code. That said, here's what I'd do:
(1) When a row is selected in mainView, present the popoverController modally:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PopoverViewController *vc = [[PopoverViewController alloc] init];
[self.navigationController presentModalViewController:vc animated:YES];
[vc release];
}
(2) When something changes in the popoverController, for example a row is selected, set a value in the parentViewController (which should be the MainView):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.parentViewController.value = someValue;
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
(3) Dismiss the popoverController where-ever you choose by calling:
[self dismissModalViewControllerAnimated:YES]`