Im making a program where im practicing UIPopoverController's for iPad
in the first popover i have a tableView with some cells , what i want to do is to call a new view with a textfield so i can add new cells with the textfield text .
The problem i have is that when i dismiss the second view the tableView is not updated . I can't call reloadData because the first view don't call "viewWillAppear" ou any other .
In the iphone simulator it works well because iphone don't use uiPopoverController but in iPad i have to dismiss the first popover and the view only reloads when i enter the second time.
I know by reading some posts that its possible to use notification center to make it happen but i don't know how
My code is this
-first view , the tableView
BNRAssetTypeViewController.h
#import <Foundation/Foundation.h>
#class BNRItem;
#interface BNRAssetTypeViewController : UITableViewController
#property (nonatomic,strong) BNRItem *item;
#property (nonatomic, copy) void (^dismissBlock)(void);
#end
BNRAssetTypeViewController.m
#import "BNRAssetTypeViewController.h"
#import "BNRItem.h"
#import "BNRItemStore.h"
#import "BNRDetailViewController.h"
#import "AddNewAssetedTypeViewController.h"
#implementation BNRAssetTypeViewController
-(instancetype)init
{
//Chamar o designated initializer
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
//Titulo
UINavigationItem *navItem = self.navigationItem;
navItem.title=#"New Asseted Type";
//Criar um novo bar button que faz novo item do lado direito
UIBarButtonItem *bbi =[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self action:#selector(addNewAssetedType)];
//meter do lado direito
navItem.rightBarButtonItem=bbi;
}
return self;
}
-(instancetype)initWithStyle:(UITableViewStyle)style
{
return [self init];
}
-(void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"ViewDidLoad");
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"UITableViewCell"];
}
-(void)viewWillAppear:(BOOL)animated
{
NSLog(#"ViewwillApear");
[self.tableView reloadData];
}
-(void)viewDidAppear:(BOOL)animated{
NSLog(#"ViewDidApear");
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[[BNRItemStore sharedStore]allAssetTypes]count];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell" forIndexPath:indexPath];
NSArray *allAssetTypes = [[BNRItemStore sharedStore]allAssetTypes];
NSManagedObject *assetType = allAssetTypes[indexPath.row];
// Use key-value coding to get the asset type's label
NSString *assetLabel = [assetType valueForKey:#"label"];
cell.textLabel.text = assetLabel;
// Checkmark the one that is currently selected
if (assetType == self.item.assetType) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType=UITableViewCellAccessoryCheckmark;
NSArray *allAssets = [[BNRItemStore sharedStore]allAssetTypes];
NSManagedObject *assetType = allAssets[indexPath.row];
self.item.assetType=assetType;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
self.dismissBlock();
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}
-(void)addNewAssetedType{
AddNewAssetedTypeViewController *anatvc = [[AddNewAssetedTypeViewController alloc]init];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:anatvc];
navController.modalPresentationStyle=UIModalPresentationCurrentContext;
[self.navigationController presentViewController:navController animated:YES completion:nil];
}
-The second View
AddNewAssetedTypeViewController.h
#import <UIKit/UIKit.h>
#interface AddNewAssetedTypeViewController : UIViewController <UITextFieldDelegate>
#property (nonatomic,copy) void (^dismissBlock)(void);
#end
AddNewAssetedTypeViewController.m
#import "AddNewAssetedTypeViewController.h"
#import "BNRItemStore.h"
#import "BNRAssetTypeViewController.h"
#interface AddNewAssetedTypeViewController ()
#property (weak, nonatomic) IBOutlet UITextField *textField;
#end
#implementation AddNewAssetedTypeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
UIBarButtonItem *doneItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(save:)];
self.navigationItem.rightBarButtonItem=doneItem;
UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:#selector(cancel:)];
self.navigationItem.leftBarButtonItem=cancelItem;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.view endEditing:YES];
[[BNRItemStore sharedStore] createAssetType:self.textField.text];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)cancel:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
-(void)save:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
#end
Olá!
You can fire a notification using NSNotificationCenter when something is added in the popover. First, register the first view controller to observe for that notification. In the first VC retain a reference to the observer you'll register later on:
#implementation BNRAssetTypeViewController {
id _observer;
}
In viewWillAppear:
_observer = [[NSNotificationCenter defaultCenter] addObserverForName:#"somethingAddedNotification"
object:nil
queue:nil
usingBlock:^(NSNotification *notification)
{
[self.tableView reloadData];
}];
In viewWillDisappear:
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:_observer];
}
Then in the method save: in the second view controller:
[[NSNotificationCenter defaultCenter] postNotificationName:#"somethingAddedNotification" object:nil];
Disclaimer: untested code. Let me know how it goes.
Related
I have a simple notes app where I have just 2 view controllers:
table view controller - to list all the notes.
view controller - to create new notes.
In the table view controller I have a segue from a cell back to the creation page where a user can edit the note in this specific cell.
But my problem is that when I'm preforming editing to a certain cell(note) I'm creating a new note with the content of what I edited...
So instead of passing the note content in the prepareForSegue method I need to pass the note object...
How can I do that?
this are my classes:
NMNote: (correctly just containing a property of *content, will add more behaviour later)
#import <Foundation/Foundation.h>
#interface NMNote : NSObject
#property (strong, nonatomic) NSString *content;
#end
NMCreateNotesViewController.h:
#import <UIKit/UIKit.h>
#import "NMNote.h"
#interface NMCreateNotesViewController : UIViewController
#property (strong, nonatomic) NMNote *note;
#property (weak, nonatomic) IBOutlet UITextView *textField;
#property (strong, nonatomic) NSString *passedInString;
#end
NMCreateNotesViewController.m:
#import "NMCreateNotesViewController.h"
#import "NMNotesListViewController.h"
#interface NMCreateNotesViewController () <UITextViewDelegate>
#property (weak, nonatomic) IBOutlet UIBarButtonItem *saveButton;
#end
#implementation NMCreateNotesViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// listen for keyboard hide/show notifications so we can properly adjust the table's height
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
#pragma mark - Notifications
- (void)adjustViewForKeyboardReveal:(BOOL)showKeyboard notificationInfo:(NSDictionary *)notificationInfo
{
// the keyboard is showing so ƒ the table's height
CGRect keyboardRect = [[notificationInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval animationDuration =
[[notificationInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect frame = self.textField.frame;
// the keyboard rect's width and height are reversed in landscape
NSInteger adjustDelta = UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? CGRectGetHeight(keyboardRect) : CGRectGetWidth(keyboardRect);
if (showKeyboard)
frame.size.height -= adjustDelta;
else
frame.size.height += adjustDelta;
[UIView beginAnimations:#"ResizeForKeyboard" context:nil];
[UIView setAnimationDuration:animationDuration];
self.textField.frame = frame;
[UIView commitAnimations];
}
- (void)keyboardWillShow:(NSNotification *)aNotification
{
[self adjustViewForKeyboardReveal:YES notificationInfo:[aNotification userInfo]];
}
- (void)keyboardWillHide:(NSNotification *)aNotification
{
[self adjustViewForKeyboardReveal:NO notificationInfo:[aNotification userInfo]];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.saveButton) return;
if (self.textField.text.length > 0) {
self.note = [[NMNote alloc] init];
self.note.content = self.textField.text;
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.passedInString != nil) {
self.textField.text = self.passedInString;
}
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
NMNotesListViewController.h:
#import <UIKit/UIKit.h>
#interface NMNotesListViewController : UITableViewController
- (IBAction) unwindToList: (UIStoryboardSegue *) segue;
#end
NMNotesListViewController.m:
#import "NMNotesListViewController.h"
#import "NMCreateNotesViewController.h"
#interface NMNotesListViewController ()
#property (strong, nonatomic) NSMutableArray *notes;
#end
#implementation NMNotesListViewController
- (IBAction) unwindToList: (UIStoryboardSegue *) segue
{
NMCreateNotesViewController *source = [segue sourceViewController];
NMNote *note = source.note;
if (note != nil) {
[self.notes addObject:note];
[self.tableView reloadData];
}
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.notes = [[NSMutableArray alloc] init];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.notes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NotesPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NMNote *note = [self.notes objectAtIndex:indexPath.row];
cell.textLabel.text = note.content;
return cell;
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(UITableViewCell *)sender
{
if ([[segue identifier] isEqualToString:#"noteSegue"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
NSInteger indx = [self.tableView indexPathForCell:sender].row;
NMNote *note = self.notes[indx];
destination.passedInString = note.content;
}
}
//#pragma mark - delegate
//
//- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
//{
//
//}
#end
This is the screens flow:
the initiate view is this table view:
Now there is the TextView where you write the note:
Now, after you save a note, you go back to the first screen. and then you can tap on a populated cell and you will segue back to this screen (the one with the TextView) so you can edit it. But instead of editing it, it will create a new one with the edited content. like this:
Please, would appreciate any help here to accomplish my task..
Thanks!
The thing you need to do when you pass the note to the NMCreateNotesViewController, is to differentiate between an edit and an add action so when you came back to the table view, you can either replace the old entry with the new edited one, or add a new entry.
The way I would approach this is to have two segues, one from the + button (I'll call it "addSegue") and one from the table view cell (call it "editSegue"). I would also create a property in the list controller to hold the value of the edited row, or set it to something like -1 to indicate it's a new note. Something like this,
#property (nonatomic) NSInteger editedRow;
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"editSegue"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
NSInteger indx = [self.tableView indexPathForCell:(UITableViewCell *)sender].row;
self.editedRow = index;
NMNote *note = self.notes[indx];
destination.note = note;
}else if ([segue.identifier isEqualToString:#"addSegue"]) {
self.editedRow = -1;
}
The prepareForSegue method in the NMCreateNotesViewController would be the same as you have in your question. You can get rid of the passedInString property since we're passing in the entire note object instead. In the unwind method in the list controller, you would do this,
- (IBAction) unwindToList: (UIStoryboardSegue *) segue {
NMCreateNotesViewController *source = [segue sourceViewController];
NMNote *note = source.note;
if (note != nil && self.editedRow == -1) {
[self.notes addObject:note];
}else{
[self.notes replaceObjectAtIndex:self.editedRow withObject:note];
}
[self.tableView reloadData];
}
in NMCreateNotesViewController.h:
#property (strong, nonatomic) NMNote *note;
#property BOOL adding;
#property (strong,nonatomic) NSString *originalContent;
Then in your NMNotesListViewController.m prepareForSegue
destination.note=self.notes[indx];
destination.adding=NO; // set adding to yes if you are adding a new note
and in your unwind
- (IBAction) unwindToList: (UIStoryboardSegue *) segue
{
NMCreateNotesViewController *source = [segue sourceViewController];
NMNote *note = source.note;
if (source.adding && note != nil) {
[self.notes addObject:note];
[self.tableView reloadData];
}
}
in NMCreateNotesViewController.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// listen for keyboard hide/show notifications so we can properly adjust the table's height
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
if (self.note != nil)
{
self.originalContent=self.note.content;
self.textField.text=self.note.content;
}
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.saveButton)
{
if (self.note != nil)
{
self.note.content=self.originalContent;
}
}
else
{
if (self.note == nil)
{
if (self.textField.text.length > 0) {
self.note = [[NMNote alloc] init];
}
self.note.content = self.textField.text;
}
}
I am having an iPad app in which I want to implement a Side Bar functionality like we have in facebook app.
I am using this Demo for this.
With this I have successfully implemented the Side Bar functionality and its working well but with that my first view doesn't show me well.
Below is the screenshot.
As you can see from the screenshot, there is a black background and my whole view is not showing in full screen when the app launches.
It should be like below.
Also on clicking the button the Side View is showing like below.
It should be small as I have taken the view size with width = 300 and height = 768.
But it is showing bigger than that.
Here is my code which I change in my appdelegate.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self createEditableCopyOfDatabaseIfNeeded];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:self.viewController];
SlidingViewController *slidingView = [[SlidingViewController alloc]initWithNibName:#"SlidingViewController" bundle:nil];
self.slideMenuController = [[SlideMenuController alloc] initWithCenterViewController:navController];
self.slideMenuController.leftViewController = slidingView;
self.window.rootViewController = navController;
[self.window makeKeyAndVisible];
return YES;
}
- (IBAction)sideBarPressed:(id)sender
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.slideMenuController.position == TKSlidePositionCenter) {
[appDelegate.slideMenuController presentLeftViewControllerAnimated:YES];
} else {
[appDelegate.slideMenuController presentCenterViewControllerAnimated:YES];
}
}
I want this for my iPad for Landscape mode only.
Please tell me What is wrong here?
I am stuck here for quite a while.
Any help will be appreciated.
Thanks in advance.
So better u need to use UISplitViewController
//in app delegate do like this
//in appDelegate.h file
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (nonatomic, retain) UISplitViewController *splitViewCOntroller;
#end
//in appDelegate.m file
#import "AppDelegate.h"
#import "SplitMasterViewController.h" //create a UITableviewController
#import "SplitViewDetailController.h" //create a UIViewController
#implementation AppDelegate
#synthesize splitViewCOntroller = _splitViewCOntroller;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
SplitMasterViewController *masterController = [[SplitMasterViewController alloc]initWithNibName:#"SplitMasterViewController" bundle:nil]; //this is the master menu controller
UINavigationController *masterNavController = [[UINavigationController alloc]initWithRootViewController:masterController];
SplitViewDetailController *detailViewController = [[SplitViewDetailController alloc]initWithNibName:#"SplitViewDetailController" bundle:nil]; //this is the master detail controller
UINavigationController *detailNavController = [[UINavigationController alloc]initWithRootViewController:detailViewController];
masterController.detailViewController = detailViewController;
_splitViewCOntroller = [[UISplitViewController alloc]init]; //initilise split controller
_splitViewCOntroller.delegate = detailViewController; //set the delegate to detail controller
_splitViewCOntroller.viewControllers = [NSArray arrayWithObjects:masterNavController,detailNavController, nil]; //set the splitview controller
self.window.rootViewController = _splitViewCOntroller; //finally your splitviewcontroller as the root view controller
[self.window makeKeyAndVisible];
return YES;
}
//in SplitMasterViewController.h this must be a table that contains your side bar menu items
#import "ViewController.h" //comment this if it shows any error
#import "SplitViewDetailController.h"
#interface SplitMasterViewController : UITableViewController<UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, retain) SplitViewDetailController *detailViewController; //to get the detailview from masterMenu controller
#property (nonatomic, retain) NSArray *Names;
#end
// in SplitMasterViewController.m file
#import "SplitMasterViewController.h"
#import "SplitViewDetailController.h"
#interface SplitMasterViewController ()
#end
#implementation SplitMasterViewController
#synthesize Names;
#synthesize detailViewController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
Names = [[NSArray alloc] initWithObjects:#"apple", #"banana",
#"mango", #"grapes", nil];
[self.tableView selectRowAtIndexPath:
[NSIndexPath indexPathForRow:0 inSection:0]
animated:NO
scrollPosition:UITableViewScrollPositionMiddle];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [Names count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// [self configureCell:cell atIndexPath:indexPath];
cell.textLabel.text = [Names objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SplitViewDetailController *detailController = self.detailViewController;
detailController.myLabel.text = [Names objectAtIndex:indexPath.row]; //set the name from the array
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
//in SplitViewDetailController.h
#import "ViewController.h"
#interface SplitViewDetailController : UIViewController<UISplitViewControllerDelegate>
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UILabel *myLabel;
#property (nonatomic, retain) UIBarButtonItem *leftBarButtonItem; //to show a button on left side
#end
//in SplitViewDetailController.m
#import "SplitViewDetailController.h"
#interface SplitViewDetailController ()
{
UIPopoverController *masterPopoverController;
}
#end
#implementation SplitViewDetailController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// _leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:#"Menu" style:UIBarButtonItemStyleBordered target:self action:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//these are the call back to detail view controller to hide or show the button
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
_leftBarButtonItem = barButtonItem;
_leftBarButtonItem.style = UIBarButtonItemStyleBordered;
_leftBarButtonItem.title = #"Menu";
[self.navigationItem setLeftBarButtonItem:_leftBarButtonItem animated:YES];
}
// Called when the view is shown again in the split view, invalidating the button
- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
}
#end
I successfully implemented this side bar menu functionality with this Demo code and its working perfectly well in my case.
Hope it works to someone else also.
Thanks for your help and suggestions.
i am using this and it's good
https://github.com/ECSlidingViewController/ECSlidingViewController
Maybe I didn't ask it right in the title, sorry for this, i'm a beginner so I will explain myself:
I have 2 screens:
1. Create notes - this screen have a view controller, TextView and navigation(with create/cancel).
2. Notes page - this screen have a table view controller and a navigation with a plus button.
(very similar to apple notes app)
I want that in the table view, whenever I click a cell it will take me back to the editable page of this note...
So I added a push segue from the cell to the notes page, and every time I'm clicking on a cell it opens a NEW note page...
So I know i'm missing something here and would really appreciate if you can help me figure it out
This is my table view controller .m file:
#import "NMNotesListViewController.h"
#import "NMCreateNotesViewController.h"
#interface NMNotesListViewController ()
#property (strong, nonatomic) NSMutableArray *notes;
#end
#implementation NMNotesListViewController
- (IBAction) unwindToList: (UIStoryboardSegue *) segue
{
NMCreateNotesViewController *source = [segue sourceViewController];
NMNote *note = source.note;
if (note != nil) {
[self.notes addObject:note];
[self.tableView reloadData];
}
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.notes = [[NSMutableArray alloc] init];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.notes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NotesPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NMNote *note = [self.notes objectAtIndex:indexPath.row];
cell.textLabel.text = note.content;
return cell;
}
#end
And this is my view controller (create notes) .m file:
#import "NMCreateNotesViewController.h"
#interface NMCreateNotesViewController ()
#property (weak, nonatomic) IBOutlet UIBarButtonItem *createButton;
#property (weak, nonatomic) IBOutlet UITextView *textField;
#end
#implementation NMCreateNotesViewController
- (void)registerForKeyboardNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWasShown:(NSNotification*)aNotification {
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect bkgndRect = self.textField.superview.frame;
bkgndRect.size.height += kbSize.height;
[self.textField.superview setFrame:bkgndRect];
[self.textField setContentOffset:CGPointMake(0.0, self.textField.frame.origin.y-kbSize.height) animated:YES];
}
- (void) keyboardWillBeHidden: (NSNotification *) aNotification
{
UIEdgeInsets contentInsets = UIEdgeInsetsZero;
self.textField.contentInset = contentInsets;
self.textField.scrollIndicatorInsets = contentInsets;
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if (sender != self.createButton) return;
if (self.textField.text.length > 0) {
self.note = [[NMNote alloc] init];
self.note.content = self.textField.text;
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
#jeely was close but what you need to do is , create a segue from viewController to viewController.
In the tableView delegate didSelectRowAtIndexPath you would preform the segue:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self performSegueWithIdentifier:#"yourSegue" sender:sender];
}
Because you want to pass the note to the next controller you will need to do that in the prepareForSegue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"yourSegue"])
{
//get the note
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NMNote *note = [self.notes objectAtIndex:indexPath.row];
//set the note
NMCreateNotesViewController *createVC = (NMCreateNotesViewController*)segue.destinationViewController;
createVC.noteToDisplay = note.content;
}
}
Finally noteToDisplay is just an NSString property that you will set to the textView property once the segue is performed.
Please bear with me, I am just starting iOS development. I am trying to display a custom tableViewCell within a storyboard tableView. I have done the following.
I have created a new .xib with a tableViewCell in it
I have then created a custom class for this. the .h file looks like this
#import <UIKit/UIKit.h>
#interface CustomTableCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *thumbnailImageView;
#property (weak, nonatomic) IBOutlet UILabel› *titleLabel;
#end
Then in my TableViewController.m I have imported the CustomTableCell.h and I am doing following for 10 rows
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
CustomTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.titleLabel.text ="test text";
return cell;
}
This seems fine to build, but when the project loads nothing happens. Any advice will be great.
I have placed a breakpoint in the cellForRowAtIndexPath method, however it never reaches this point. here is a screen shot of the simulator
You must register your .xib file. In your viewDidLoad method, add the following:
[self.tableView registerNib:[UINib nibWithNibName:#"CustomTableCell" bundle:nil]
forCellReuseIdentifier:#"CustomTableCell"];
The way you are loading the nib is really old-fashioned and outdated. It is much better (since iOS 6) to register the nib and use dequeueReusableCellWithIdentifier:forIndexPath:.
See my explanation of all four ways of getting a custom cell.
Ensure that the delegate and datasource are set in the storyboard for the UITableView. This will ensure that cellForRowAtIndexPath is getting called for each row. You can put an NSLog message in that method to verify the same thing.
Also, since you are using a storyboard, you may want to look into Prototype Cells for the UITableView. They are a much easier way of doing the same thing - creating a UITableView with custom cells.
Here's a decent tutorial on using Prototype cells within your storyboard's UITableView:
http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1
- (void) viewDidLoad {
[super viewDidLoad];
UINib *cellNib = [UINib nibWithNibName:#"CustomTableCell" bundle:[NSBundle mainBundle]];
[self.tableView registerNib:cellNib forCellReuseIdentifier:#"CustomTableCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
CustomTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.titleLabel.text ="test text";
return cell;
}
A very basic question, but have you implemented the tableview delegate method that indicates how many cells should be displayed? The delegate method is the following:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//Return number of cells to display here
return 1;
}
Be sure to have only one item in your xib (Uitableviewcell instance)
#import <UIKit/UIKit.h>
#import "DetailViewController.h"
#import "NewViewController.h"
#import "CustomCellVC.h"
#interface FirstVC : UIViewController
{
DetailViewController *detailViewController;
NewViewController *objNewViewController;
CustomCellVC *objCustom;
NSMutableData *webData;
NSArray *resultArray;
//IBOutlet UIButton *objButton;
}
#property(strong,nonatomic)IBOutlet DetailViewController *detailViewController;
#property(strong,nonatomic)IBOutlet UITableView *objTable;
-(void)loginWS;
-(IBAction)NewFeatureButtonClk:(id)sender;
#end
#import "FirstVC.h"
#interface FirstVC ()
#end
#implementation FirstVC
#synthesize objTable;
#synthesize detailViewController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
objTable.frame = CGRectMake(0, 20, 320, 548);
[self loginWS];
}
-(void)loginWS
{
//Para username password
NSURL *url = [NSURL URLWithString:#"http://192.168.0.100/FeatureRequestComponent/FeatureRequestComponentAPI"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:#"POST"];
[req addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
// [req addValue:[NSString stringWithFormat:#"%i",postBody.length] forHTTPHeaderField:#"Content-Length"];
[req setTimeoutInterval:60.0 ];
//[req setHTTPBody:postBody];
//[cell setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"CellBg.png"]]];
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:req delegate:self];
if (connection)
{
webData = [[NSMutableData alloc]init];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:webData options:0 error:nil];
resultArray = [[NSArray alloc]initWithArray:[responseDict valueForKey:#"city"]];
NSLog(#"resultArray: %#",resultArray);
[self.objTable reloadData];
}
-(IBAction)NewFeatureButtonClk:(id)sender
{
objNewViewController=[[NewViewController alloc]initWithNibName:#"NewViewController" bundle:nil];
// Push the view controller.
[self.navigationController pushViewController:objNewViewController animated:YES];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//#warning Incomplete method implementation.
// Return the number of rows in the section.
return [resultArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
objCustom = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (objCustom == nil) {
objCustom = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//objCustom.persnName.text=[[resultArray objectAtIndex:indexPath.row]valueForKey:#"Name"];
//objCustom.persnAge.text=[[resultArray objectAtIndex:indexPath.row]valueForKey:#"Age"];
// Configure the cell...
objCustom.textLabel.text = [[resultArray objectAtIndex:indexPath.row] valueForKey:#"FeatureTitle"];
objCustom.detailTextLabel.text = [[resultArray objectAtIndex:indexPath.row] valueForKey:#"Description"];
return objCustom;
}
#pragma mark - Table view delegate
// In a xib-based application, navigation from a table can be handled in -tableView:didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here, for example:
// Create the next view controller.
detailViewController = [[DetailViewController alloc]initWithNibName:#"DetailViewController" bundle:nil];
detailViewController.objData=[resultArray objectAtIndex:indexPath.row];
// Pass the selected object to the new view controller.
// Push the view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
#import <UIKit/UIKit.h>
#import "DetailData.h"
#interface DetailViewController : UIViewController
{
DetailData *objData;
}
#property(strong,nonatomic)IBOutlet UITextField *usecaseTF;
#property(strong,nonatomic)IBOutlet UITextView *featureTF;
#property(strong,nonatomic)IBOutlet UILabel *priority;
#property(strong,nonatomic)IBOutlet UIButton *voteBtn;
#property(strong,nonatomic)IBOutlet DetailData *objData;
-(IBAction)voteBtnClk:(id)sender;
#end
#import "DetailViewController.h"
#interface DetailViewController ()
#end
#implementation DetailViewController
#synthesize objData,usecaseTF,featureTF,priority,voteBtn;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
usecaseTF.text=objData.usecaseTF;
featureTF.text=objData.featureTF;
priority.text=objData.priority;
}
-(IBAction)voteBtnClk:(id)sender
{
if ([voteBtn.currentImage isEqual:#"BtnGreen.png"])
{
[voteBtn setImage:[UIImage imageNamed:#"BtnBlack.png"] forState:UIControlStateNormal];
}
else
{
[voteBtn setImage:[UIImage imageNamed:#"BtnGreen.png"] forState:UIControlStateNormal];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
#import <UIKit/UIKit.h>
#interface NewViewController : UIViewController<UITextFieldDelegate>
{
UITextField *currentTF;
}
#property(strong,nonatomic) IBOutlet UITextField *nameTF;
#property(strong,nonatomic)IBOutlet UITextField *emailTF;
#property(strong,nonatomic)IBOutlet UITextField *featureTF;
#property(strong,nonatomic)IBOutlet UITextField *descpTF;
#property(strong,nonatomic)IBOutlet UITextView *UsecaseTV;
#property(strong,nonatomic)IBOutlet UIButton *HighBtn;
#property(strong,nonatomic)IBOutlet UIButton *LowBtn;
#property(strong,nonatomic)IBOutlet UIButton *MediumBtn;
-(IBAction)sendRequestBtnClk:(id)sender;
-(IBAction)RadioBtnHigh:(id)sender;
-(IBAction)RadioBtnLow:(id)sender;
-(IBAction)RadioBtnMedium:(id)sender;
-(void)radioBtnClick;
#end
#import "NewViewController.h"
#interface NewViewController ()
#end
#implementation NewViewController
#synthesize nameTF,emailTF,featureTF,descpTF,UsecaseTV,LowBtn,HighBtn,MediumBtn;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.title=#"Did I Know This";
currentTF=[[UITextField alloc]init];
[ self radioBtnClick];
}
-(IBAction)sendRequestBtnClk:(id)sender
{
if (nameTF.text.length==0)
{
[self showAlertMessage:#"Please enter Your Name"];
// return NO;
}
else if (emailTF.text.length==0)
{
[self showAlertMessage:#"Please enter email ID"];
}
if (emailTF.text.length==0)
{
[self showAlertMessage:#"Please enter email address"];
}
else if ([self emailValidation:emailTF.text]==NO)
{
[self showAlertMessage:#"Please enter valid email address"];
}
else if(featureTF.text.length==0)
{
[self showAlertMessage:#"Please Confirm the Feature title"];
}
}
-(BOOL) emailValidation:(NSString *)emailTxt
{
NSString *emailRegex = #"[A-Z0-9a-z._%+-]+#[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", emailRegex];
return [emailTest evaluateWithObject:emailTxt];
}
-(void)showAlertMessage:(NSString *)msg
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Note" message:msg delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
#pragma mark TextField Delegates
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[currentTF resignFirstResponder];
return YES;
}
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
currentTF = textField;
[self animateTextField:textField up:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
currentTF = textField;
[self animateTextField:textField up:NO];
}
-(void)animateTextField:(UITextField*)textField up:(BOOL)up
{
int movementDistance = 0; // tweak as needed
if (textField.tag==103||textField.tag==104||textField.tag==105||textField.tag==106)
{
movementDistance = -130;
}
else if (textField.tag==107||textField.tag==108)
{
movementDistance = -230;
}
else
{
movementDistance = 00;
}
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? movementDistance : -movementDistance);
[UIView beginAnimations: #"animateTextField" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
-(void)radioBtnClick
{
if ([HighBtn.currentImage isEqual:#"radiobutton-checked.png"])
{
[LowBtn setImage:[UIImage imageNamed:#"radiobutton-checked.png"] forState:UIControlStateNormal];
[MediumBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
[HighBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
}
else
{
[LowBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
[HighBtn setImage:[UIImage imageNamed:#"radiobutton-checked.png"] forState:UIControlStateNormal];
[MediumBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
}
}
-(IBAction)RadioBtnHigh:(id)sender
{
[LowBtn setImage:[UIImage imageNamed:#"radiobutton-checked.png"] forState:UIControlStateNormal];
[HighBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
[MediumBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
}
-(IBAction)RadioBtnLow:(id)sender
{
[LowBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
[HighBtn setImage:[UIImage imageNamed:#"radiobutton-checked.png"] forState:UIControlStateNormal];
[MediumBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
}
-(IBAction)RadioBtnMedium:(id)sender
{
[LowBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
[HighBtn setImage:[UIImage imageNamed:#"radiobutton-unchecked.png"] forState:UIControlStateNormal];
[MediumBtn setImage:[UIImage imageNamed:#"radiobutton-checked.png"] forState:UIControlStateNormal];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
#import <UIKit/UIKit.h>
#interface CustomCellVC : UITableViewCell
#property (strong,nonatomic) IBOutlet UIImageView *persnImage;
#property (strong,nonatomic) IBOutlet UIButton *thumbImage;
#property (strong,nonatomic) IBOutlet UIImageView *calenderImage;
#property (strong,nonatomic) IBOutlet UIButton *voteImage;
#property (strong,nonatomic) IBOutlet UIButton *selectImage;
#property (strong,nonatomic) IBOutlet UILabel *publabel;
#property (strong,nonatomic) IBOutlet UILabel *IdLabel;
#property (strong,nonatomic) IBOutlet UILabel *decpLabel;
#property (strong,nonatomic) IBOutlet UITextField *ansTF;
#end
#import "CustomCellVC.h"
#implementation CustomCellVC
#synthesize ansTF,persnImage,publabel,thumbImage,calenderImage,voteImage,selectImage,IdLabel,decpLabel;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
#end
#synthesize ObjFirstVC,objNavc;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
ObjFirstVC=[[FirstVC alloc ]initWithNibName:#"FirstVC" bundle:nil];
objNavc=[[UINavigationController alloc]initWithRootViewController:ObjFirstVC];
[self.window addSubview:objNavc.view];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
#import <Foundation/Foundation.h>
#interface DetailData : NSObject
#property(strong,nonatomic)IBOutlet UITextField *usecaseTF;
#property(strong,nonatomic)IBOutlet UITextView *featureTF;
#property(strong,nonatomic)IBOutlet UILabel *priority;
#property(strong,nonatomic)IBOutlet UIButton *voteBtn;
#end
I have a tableview controller that is a static table used for request data. When someone selects a row, it displays a new tableview controller with options using a modal segue, the user selects a option and then presses the 'hecho' (done) button and the value should be returned to the first table view controller, but it just not happening. If I inspect the delegate it just says null. What could I be doing wrong?
The story board
First table
AgregarCitaTableViewController.h
#import <UIKit/UIKit.h>
#import "SeleccionarPacienteTableViewController.h"
#interface AgregarCitaTableViewController : UITableViewController <SeleccionarPacienteTableViewControllerDelegate>
#end
AgregarCitaTableViewController.m
#import "AgregarCitaTableViewController.h"
#import "SeleccionarPacienteTableViewController.h"
#interface AgregarCitaTableViewController ()
{
NSDictionary *datosPaciente;
}
#end
#implementation AgregarCitaTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)paciente:(NSDictionary *)paciente
{
datosPaciente = paciente;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
cell.detailTextLabel.text = [datosPaciente objectForKey:#"nombre"];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"listaPacientes"] )
{
SeleccionarPacienteTableViewController *viewController = segue.destinationViewController;
viewController.delegate = self;
}
}
Second Table
SeleccionarPacienteTableViewController.h
#protocol SeleccionarPacienteTableViewControllerDelegate <NSObject>
-(void)paciente:(NSDictionary *)paciente;
#end
#interface SeleccionarPacienteTableViewController : UITableViewController
{
id delegate;
}
#property(nonatomic,assign)id<SeleccionarPacienteTableViewControllerDelegate> delegate;
#end
SeleccionarPacienteTableViewController.m
#import "SeleccionarPacienteTableViewController.h"
#interface SeleccionarPacienteTableViewController ()
{
NSMutableArray *todosPacientes;
NSDictionary *paciente;
NSInteger checkmarkedRow;
}
#end
#implementation SeleccionarPacienteTableViewController
#synthesize delegate = _delegate;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
UIBarButtonItem *hecho = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(hecho)];
[[self navigationItem] setRightBarButtonItem:hecho];
UIBarButtonItem *cancelar = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelar)];
[[self navigationItem] setLeftBarButtonItem:cancelar];
//Llamada asincrona, cargar las citas
[self performSelectorInBackground:#selector(cargarDatos) withObject:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return todosPacientes.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSDictionary *object;
object = todosPacientes[indexPath.row];
cell.textLabel.text = [object objectForKey:#"nombre"];
if(checkmarkedRow == indexPath.row){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Guardar nombre del paciente selccionado
paciente = todosPacientes[indexPath.row];
// In cellForRow... we check this variable to decide where we put the checkmark
checkmarkedRow = indexPath.row;
// We reload the table view and the selected row will be checkmarked
[tableView reloadData];
// We select the row without animation to simulate that nothing happened here :)
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
// We deselect the row with animation
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void) cargarDatos
{
//Path donde se encuentra el plist con los datos
NSString *path = [[NSBundle mainBundle]pathForResource:#"pacientes" ofType:#"plist"];
//Guardamos las citas en un NSMutableArray
todosPacientes = [[NSMutableArray alloc]initWithContentsOfFile:path];
}
- (void) hecho
{
/*Is anyone listening
if([delegate respondsToSelector:#selector(paciente:)])
{
//send the delegate function with the amount entered by the user
[delegate paciente:paciente];
}*/
[self.delegate paciente:paciente];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void) cancelar
{
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
Solution:
Im not really sure how it worked or even if this is the real solution. I used the anwer of Hani Ibrahim and it didn't work but what he said was right. Then i just changed [delegate paciente:paciente] in the hecho method for [self.delegate paciente:paciente] and it worked.
I hope this can help someone.
The problem is that your seque display UINavigationController and not SeleccionarPacienteTableViewController
Change this method
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"listaPacientes"] )
{
SeleccionarPacienteTableViewController *viewController = segue.destinationViewController;
viewController.delegate = self;
}
}
to be
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if( [segue.identifier isEqualToString:#"listaPacientes"] )
{
UINavigationController *navController = segue.destinationViewController;
SeleccionarPacienteTableViewController *viewController = [navController.viewControllers objectAtIndex:0];
viewController.delegate = self;
}
}
You have another problem
When doing this
#property(nonatomic,assign)id<SeleccionarPacienteTableViewControllerDelegate> delegate;
and this
#synthesize delegate = _delegate;
Then Your property will work with an instance variable called '_delegate' as you are saying #synthesize delegate = _delegate;
However this code
#interface SeleccionarPacienteTableViewController : UITableViewController
{
id delegate;
}
defines a new instance variable called delegate which is completely different than your property
So to access your property you can use self.delegate or _delegate and NOT delegate as it is another instance variable !
I think the problem is in prepareForSegue. The destinationViewController is a UINavigationController and not a SeleccionarPacienteTableViewController.
You have to access the first child of the destinationViewController to get your SeleccionarPacienteTableViewController.
Replacing segue.destinationViewController with [segue.destinationViewController topViewController] will probably solve your problem.