Changing title in UINavigationBar when a row from UITableView is touched - ios

Ok, so I have tried this a lot of different ways...
At the moment I have placed the UINavigationBar with the IB. Then declared it with IBOutlet.
From there I can't seem to change the title no matter what i try. Even just in ViewDidLoad.
Also, I dont need to assign the delegate of the navbar do i?
Here is my code:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController < UITableViewDataSource, UITableViewDelegate>
{
NSArray *myArrayOne;
NSArray *myArrayTwo;
UITextView *myTextView;
UINavigationBar *myNavBar;
}
#property (nonatomic, retain) NSArray *myArrayOne;
#property (nonatomic, retain) NSArray *myArrayTwo;
#property (nonatomic, retain) IBOutlet UITextView *myTextView;
#property (nonatomic, retain) IBOutlet UINavigationBar *myNavBar;
#end
and:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
//Synthesising anything with a property call in the .h file.
#synthesize myArrayOne;
#synthesize myArrayTwo;
#synthesize myTextView;
#synthesize myNavBar;
- (void)viewDidLoad
{
//declaring and instantiating datapaths and also
// reading into arrays from plist.
NSString *datapath1 = [[NSBundle mainBundle] pathForResource:#"myListOne" ofType:#"plist"];
NSString *datapath2 = [[NSBundle mainBundle] pathForResource:#"myListTwo" ofType:#"plist"];
myArrayOne = [[NSArray alloc] initWithContentsOfFile:datapath1];
myArrayTwo = [[NSArray alloc] initWithContentsOfFile:datapath2];
self.navigationItem.title = #"Hi";
[super viewDidLoad];
}
#pragma mark - TableView Delegate stuff
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//myNavBar.title = [myArrayOne objectAtIndex:indexPath.row];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark - TableView Datasource stuff
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//returns amount of items inside myArrayOne as amount of rows
return [myArrayOne count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *myCell = nil;
myCell = [tableView dequeueReusableCellWithIdentifier:#"myReuseCell"];
if (myCell == nil)
{
myCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myReuseCell"];
}
myCell.textLabel.text = [myArrayOne objectAtIndex:indexPath.row];
return myCell;
}
#end
the actual code to change the title is just one way i have tried...
Any other way? And do I need to link the navigationbar in the IB with anything?

If you have a navigation bar without a navigation controller, you have to give it a stack (in your case, a stack of one) navigation items.
In viewDidLoad of your view controller, add your view controller's navigation item to the stack:
self.myNavBar.items = #[self.navigationItem];
Now you can set the title like so:
self.navigationItem.title = #"Hello";
and it will appear in your navigation bar.

The solution above by jrturton works fine UNLESS you also have a UIBarButtonItem (e.g. a "Done" button) in the UINavigationBar. In that case, the proposed solution causes the UIBarButtonItem to disappear.
Here's how to do it in a way that lets you change the UINavigationBar title but also preserve the UIBarButtonItem:
Add IBOutlet UINavigationItem *myNavigationItem; to your code.
In IB, in the outline view (not the storyboard view), right click the containing UIViewController and drag to the UINavigationItem that was automatically created by IB inside the UINavigationBar and connect to myNavigationItem.
Back in your code, add self.myNavigationItem.title = #"Hello";

I think you need to have a navigationController instead why don't you check this link:
create navigation bar for tableView programmatically in objective-C
and if you already have a navigation controller in your app delegate, then you should remove the IBoutlet you've created then use:
self.navigationItem.title = #"Hi";
for this will be referring the navigationController in your app delegate.

Related

XCode TableViewController to detail in Objective-C

I have a TabBarController with 4 tabs, 3 of which are table views. I am trying to put a detail for every table view cell, and I don't think storyboard is efficient since I have over 50 detail pages. I'm very new to all of this, and I've tried to find out how to link a detail to every tab for a couple hours. My table views start with the Second View Controller.
Here is SecondViewController.m:
#import "SecondViewController.h"
#implementation SecondViewController
{
NSArray *tableData;
}
#synthesize tableData;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
tableData = [NSArray arrayWithObjects:#"Carter", #"Greene", #"Hancock", #"Hawkins", #"Johnson", #"Sullivan", #"Unicoi", #"Washington", nil];
[super viewDidLoad];
}
#pragma mark - TableView Data Source methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
#end
Here is SecondViewController.h:
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController <UITableViewDelegate,
UITableViewDataSource>
#property(nonatomic, retain) NSArray *tableData;
#end
If this helps, here is my storyboard.
If anyone can help me individually add details to each table view cell in the most painless way possible, I would appreciate it. Thanks!
If using storyboards, the process is fairly simple.
First, I'd suggest dragging a prototype "table view cell" on to your table views. You can then control-drag from that prototype cell to your destination scene to add a segue between the cell and the next scene:
Make sure to select that prototype cell and set its storyboard identifier (I used "Cell"). You will need to reference that storyboard identifier, as shown in my code sample below. I also configured appearance related things (like the disclosure indicator) right in that cell prototype in IB so I don't have to worry about doing that in code and I can see what the UI will look like right in IB.
Now you can go to the table view controller and (a) simplify cellForRowAtIndexPath (because you don't need that logic about if (cell == nil) ... when using cell prototypes); but also implement a prepareForSegue to pass the data to the destination scene:
// SecondViewController.m
#import "SecondViewController.h"
#import "DetailsViewController.h"
#interface SecondViewController ()
#property (nonatomic, strong) NSArray *tableData;
#end
#implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableData = #[#"Carter", #"Greene", #"Hancock", #"Hawkins", #"Johnson", #"Sullivan", #"Unicoi", #"Washington"];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.destinationViewController isKindOfClass:[DetailsViewController class]]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *name = self.tableData[indexPath.row];
[(DetailsViewController *)segue.destinationViewController setName:name];
}
}
- (IBAction)unwindToTableView:(UIStoryboardSegue *)segue {
// this is intentionally blank; but needed if we want to unwind back here
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.tableData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.tableData[indexPath.row];
return cell;
}
#end
Obviously, this assumes that you created a DetailsViewController and specified it as the destination scene's base class, and then create properties for any values you want to pass to this destination scene:
// DetailsViewController.h
#import <UIKit/UIKit.h>
#interface DetailsViewController : UIViewController
#property (nonatomic, copy) NSString *name;
#end
And this destination scene would then take the name value passed to it and fill in the UILabel:
// DetailsViewController.m
#import "DetailsViewController.h"
#interface DetailsViewController ()
#property (weak, nonatomic) IBOutlet UILabel *nameLabel;
#end
#implementation DetailsViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.nameLabel.text = self.name;
}
#end
Frankly, this process will undoubtedly be described more clearly in any UITableView tutorial includes a discussion of "cell prototypes" (your code sample suggests you were using an older tutorial that predates cell prototypes).
I think the relationship between the code and the storyboard is as following:
Code implement the function of the application.
Storyboard contains many scenes, these scenes implement the User interface, including data presentation, data input, data output.
Code read data from these scenes and output the result to the scenes.
Code is internal logic function entities and the storyboard the the User Interface presentation.

Custom UITableViewCell Class Issue

I've read quite a few tutorials online about how to create a custom cell subclass, but I'm still a little confused. When I try to follow the instructions found in this question, I end up with errors that the tableView is not a valid property for the object of ViewController.
I've created a new subclass of UITableViewCell, called CustomBookClass. I've hooked up the properties with my CustomBookClass.h file.
#import <UIKit/UIKit.h>
#interface CustomBookCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *bookImage;
#property (weak, nonatomic) IBOutlet UILabel *bookTitle;
#property (weak, nonatomic) IBOutlet UILabel *dateAdded;
#end
I then go into my ViewController.m file to edit the viewDidLoad method.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView.delegate = self];
[self.tableView.dataSource=self];
[self.tableView registerClass:[CustomBookCell class]forCellReuseIdentifier:#"Custom
Cell"];
}
I get an error on the tableView, saying the property doesn't exist, even though in the ViewController.h file, I'm including the table view.
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDelegate,
UITableViewDataSource>
#end
I'm sure I'm missing something really obvious here, as this is my first time trying this. Can anyone help me out? Thanks!
UIViewController does not have that property. Even if you assign the Delegate and DataSource protocols to it. There are a couple of things you can do however.
Link the table view to the ViewController yourself. That means, create a property/outlet called tableView.
Inherit from UITableViewController instead of UIViewController.
Both should work.
Edit: Oh and the lines:
[self.tableView.delegate = self];
[self.tableView.dataSource=self];
don't make sense. They should be either:
self.tableView.delegate = self; and self.tableView.dataSource = self;
Or [self.tableView setDelegate:self]; and [self.tableView setDataSource:self]
with 1 being preferred. (Edit: option #2 was actually incorrect code, my bad.)
No need to set delegate and datasource in TableViewCell class
simple make a property and synthesize your table view item
#property (weak, nonatomic) IBOutlet UIImageView *bookImage;
#property (weak, nonatomic) IBOutlet UILabel *bookTitle;
#property (weak, nonatomic) IBOutlet UILabel *dateAdded;
now import your cell class in your tableView controller class
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
//If you are using xib for representing your UI then add a nib file.
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.bookTitle.text = [tableData objectAtIndex:indexPath.row];
cell.bookImage.image = [UIImage imageNamed:[thumbnails objectAtIndex:indexPath.row]];
cell.dateAdded.text = [prepTime objectAtIndex:indexPath.row];
return cell;
}
for more detail check this link

Xcode - didSelectRowAtIndexPath doesn't run

i have this simple code in the didSelectRowAtIndexPath method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
NSString *selected = #"test";
NSLog(#"You choose: %#", selected);
}
This is my ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
IBOutlet UITableView *tableData;
}
#end
When i run the App, the TableView display all data, but then i cliked in a cell the method above doesn't run (?)
Have you set the delegate for the tableview in your storyboard, select your table view right click and drag to the view controller and you should see the option to set dataSource delegate and tableviewdelegate - I forget the exact names.
e.g.: thats part of my code, but should show you what you need to do. You need to hand over the data somewhere.
NSDictionary *oneDict = [_noteBookArray objectAtIndex:indexPath.row];
NSString *touchString = [oneDict objectForKey:#"value"];
NSString *dateString = [oneDict objectForKey:#"timestamp"];
//call the method who does it
[_noteBookViewController setContentAndTimeStampWith:touchString and:dateString];
//set the present View Controller active (the controller who contains the values)
[self presentViewController:_noteBookViewController animated:YES completion:nil];
method from the notebookviewcontroller
- (void)setContentAndTimeStampWith:(NSString *)contentString and:(NSString *)timeStampString
{_textInputView.text = contentString;
_timeStampString = timeStampString;}
got it?

Passing cell title to another view controller

today i have this problem:
Im doing so the title of the First cell of a tableview is show in my "Home" view controller.
This is what i have dun at the moment, but the label in homeviewcontroller is not getting the title text of the first cell.
Reminders.h:
NSMutableString *primerevento;
#property (strong, nonatomic) NSMutableString *primerevento;
Reminders.m:
#synthesize primerevento;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
....
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if(indexPath.row == 1){
cell.textLabel.text = primerevento;
}
HomeViewController.h
#property (weak, nonatomic) IBOutlet UILabel *promediototal;
HomeViewController.m
#synthesize promediototal
- (void)viewDidLoad
{
[super viewDidLoad];
....
Reminders *viewsiguiente = [[Reminders alloc] initWithNibName:nil bundle:nil];
promediototal.text = viewsiguiente.primerevento;
[self presentViewController:viewsiguiente animated:YES completion:NULL];
my label on homeviewcontroller appears in blanc, i dont know what im doing wrong, im really trying.
Thanks for your time guys
In the homeViewController don't forget to import the .h of the remindersViewController.
#import "reminders.h"
#property (weak, nonatomic) IBOutlet UILabel *promediototal;
Then in the homeViewController.m where you want your text - promediototal.text = reminders.primerevento.text;
#synthesize promediototal
- (void)viewDidLoad
{
[super viewDidLoad];
....
Reminders *viewsiguiente = [[Reminders alloc] initWithNibName:nil bundle:nil];
promediototal.text = reminders.primerevento.text;
[self presentViewController:viewsiguiente animated:YES completion:NULL];
We have probably still too view code to understand what you are up to.
There is one thing though:
Reminders *viewsiguiente = [[Reminders alloc] initWithNibName:nil bundle:nil];// 1)
promediototal.text = viewsiguiente.primerevento; // 2)
[self presentViewController:viewsiguiente animated:YES completion:NULL]; // 3)
1) What is the purpose of that? Firstyou create a brand new view controller object. As you do not create it from nib (which is fine) it cannot have any poperties set. so viewsiguiente.primerevento is nil at that point of time.
2) Now you take this nil value and assign it to promeditional.text which becomes nil to? What is the sense in that? Did you mean?
viewsiguiente.primerevento = promediototal.text;
3) And now you present the newly created view controller viewsiguiente. You did not make any changes to it. That may be fine if you implementation of Reminders takes care of the views. But you did not set any value from external.

xCode Detail View is Empty

I am creating an iPad application (iOS6.1) which has a master detail view concept. First view is a table view has list of items that are been loaded from Plist, when each row gets selected the second table view gets loaded with another Plist. theirs is my Detail view which has to display an UIView with a UILabel ans an UIImage. I am using didSelectRowAtIndexPath method . The first two table Views are been displayed properly and loads the row and display corresponding View but the last detail view which is supposed to display the UILabel and an image is empty, can any one help me to solve this problem
My Code for the didSelectRowAtIndexPath method is
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TaskDetailViewController *newTaskDetailViewController = [[TaskDetailViewController alloc] init];
// pass the row to newDetailViewController
if (weekNumber == 0)
{
newTaskDetailViewController.taskdescription = [weeklist1 objectAtIndex:indexPath.row];
}
if (weekNumber == 1)
{
newTaskDetailViewController.taskdescription = [weeklist2 objectAtIndex:indexPath.row];
}
if (weekNumber == 2)
{
newTaskDetailViewController.taskdescription = [weeklist3 objectAtIndex:indexPath.row];
}
// ...... repeated for 39 times because of the list
newTaskDetailViewController.taskNumber = indexPath.row;
[self.navigationController pushViewController:newTaskDetailViewController animated:YES];
}
DetailView header
#import <UIKit/UIKit.h>
#interface TaskDetailViewController : UIViewController
#property int taskNumber;
#property(strong , nonatomic) NSString *taskdescription;
#property (nonatomic , strong) NSMutableDictionary * tasks;
#property (strong, nonatomic) IBOutlet UIImageView *questionImage;
#property (strong, nonatomic) IBOutlet UILabel *displayText;
#end
Implemetation file has
#implementation TaskDetailViewController
#synthesize taskNumber;
#synthesize taskdescription;
#synthesize tasks;
#synthesize displayText;
#synthesize questionImage;
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = taskdescription;
NSLog(#"%#", taskdescription);
}
Your problem is using alloc init to create an instance of TaskDetailViewController. You've created that controller in the storyboard so you should instantiate it from the storyboard using an identifier that you give it (DetailViewController in my example):
TaskDetailViewController *newTaskDetailViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];

Resources