Im having a problem connecting the different tableViewCells to different UiTableViewControllers. The first cellrow gets connected to the right TableViewController but after that cant get any further because I really dont know how to set the "else if" statement here.
Thanks in advance!
Please see the .m(master):
#import "GuideTableViewController.h"
#import "GuideDetailTableViewController.h"
#import "GuideDetailTableViewController2.h"
#import "GuideDetailTableViewController3.h"
#import <QuartzCore/QuartzCore.h>
#interface GuideTableViewController (){
NSArray *guide;
NSMutableData *weatherResponseData;
}
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (weak, nonatomic) IBOutlet UIImageView *imgHeader;
#property (weak, nonatomic) IBOutlet UIImageView *ImgTitle;
#property (weak, nonatomic) IBOutlet UIImageView *ImgWeather;
#property (weak, nonatomic) IBOutlet UIButton *btnMap;
#property (weak, nonatomic) IBOutlet UILabel *LabelWeather;
#end
#implementation GuideTableViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
//JSON method
- (void) loadJSON{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//code
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"https://dl.dropbox.com/u/100670549/test.json"]];
NSError *error;
if (data)
{
guide = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
for (NSDictionary *dictionary in guide){
//NSLog([dictionary description]);
}
}else
{
NSLog(#"Could not load data");
}
dispatch_sync(dispatch_get_main_queue(), ^{
// code
[self.tableView reloadData];
});
});
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Call json
[self loadJSON];
[self loadWeather];
//set background
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.jpg"]];
//rounded corners
[self.tableView.layer setCornerRadius:9.0];
[self.ImgWeather.layer setCornerRadius:9.0];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//TableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 3;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
NSDictionary *dict = [guide objectAtIndex:indexPath.row];
cell.textLabel.text = [dict valueForKey:#"title"];
return cell;
}
//To detailView
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showStay"]){
GuideDetailTableViewController *tvc = [segue destinationViewController];
NSIndexPath *index = sender;
NSDictionary *dict = [guide objectAtIndex:index.row];
tvc.stay = dict;
}
else if([segue.identifier isEqualToString:#"showEat"]){
GuideDetailTableViewController2 *tvc = [segue destinationViewController];
NSIndexPath *index = sender;
NSDictionary *dict = [guide objectAtIndex:index.row];
tvc.eat = dict;
}
else if([segue.identifier isEqualToString:#"showDo"]){
GuideDetailTableViewController3 *tvc = [segue destinationViewController];
NSIndexPath *index = sender;
NSDictionary *dict = [guide objectAtIndex:index.row];
tvc.todo = dict;
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self performSegueWithIdentifier:#"showStay" sender:indexPath];
}
- (void) viewWillAppear:(BOOL)animated{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.tableView.indexPathForSelectedRow];
//ta bort markeringen när man går tillbaka till master från detailView.
[cell setSelected:NO];
//Hide navbar
[self.navigationController setNavigationBarHidden:YES];
}
//Show navbar in detailView
-(void)viewWillDisappear:(BOOL)animated{
[self.navigationController setNavigationBarHidden:NO];
}
#end
Related
I have a HabitViewController (UITableViewController) with a button to add cells. When a cell is added its default title is "New Habit". Then the user can tap the cell and a detailViewController appears with a picker to choose the habit. The cell.label.text is then set to the selected option in the picker. This is where my problem is. For example, if i added 3 cells by pressing the button three times, then selected the third row. And then I chose the option Hello World. The top cell would be named hello world, not the third cell. Is this normal? Here is my code:
HabitViewController.h
#import <UIKit/UIKit.h>
#import "DetailViewController.h"
#interface HabitViewController : UITableViewController <DetailViewDelegate> {
}
#property (nonatomic, strong) NSString *cellNameSender;
#property (strong, nonatomic) IBOutlet UITableView *tableView;
#property (strong, nonatomic) NSIndexPath *selectedCell;
#end
.m
#import "HabitViewController.h"
#import "DetailViewController.h"
#interface HabitViewController () {
NSMutableArray *myCells;
}
#property(strong, nonatomic) NSString *cellName2;
#end
#implementation HabitViewController
#synthesize cellNameSender, selectedCell;
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
[self.editButtonItem setTintColor:[UIColor colorWithRed:.33 green:.33 blue:.33 alpha:1]];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
addButton.tintColor = [UIColor colorWithRed:.33 green:.33 blue:.33 alpha:1];
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"nav_bar.png"] forBarMetrics:UIBarMetricsDefault];
}
- (void)viewDidAppear:(BOOL)animated {
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)insertNewObject:(id)sender
{
if (!myCells) {
myCells = [[NSMutableArray alloc] init];
}
[myCells insertObject:#"New Habit" atIndex:0];
NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[path] withRowAnimation:UITableViewRowAnimationAutomatic];
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return myCells.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = myCells[indexPath.row];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[myCells removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
}
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
DetailViewController *vc = segue.destinationViewController;
vc.delegate = self;
}
#pragma mark - DetailViewDelegate
-(void)setCellName2:(NSString *)cellName {
NSInteger selectedRow = [self.tableView indexPathForSelectedRow].row;
[myCells replaceObjectAtIndex:selectedRow withObject:cellName];
[self.tableView reloadData];
}
#end
DetailViewController.h
#import <UIKit/UIKit.h>
#protocol DetailViewDelegate <NSObject>
- (void)setCellName2:(NSString *)cellName;
#end
#interface DetailViewController : UIViewController<UIPickerViewDelegate> {
NSArray *PickerData;
}
#property (weak, nonatomic) IBOutlet UITextField *habitField;
#property (strong, nonatomic) UIToolbar *toolBar;
#property (weak, nonatomic) id<DetailViewDelegate> delegate;
#property (nonatomic, strong) NSString *cellName;
#property (nonatomic, strong) UIBarButtonItem *backButton;
#property (nonatomic, strong) UIPickerView *Picker;
#property (retain, nonatomic) NSArray *PickerData;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *doneButton;
#property (nonatomic, strong) UIBarButtonItem *barDoneButton;
#property (nonatomic, strong) UIBarButtonItem *flexSpace;
#property (nonatomic, strong) NSString *customHabit;
- (IBAction)backToRoot:(id)sender;
#end
.m
#import "DetailViewController.h"
#import "HabitViewController.h"
#interface DetailViewController () {
}
#end
#implementation DetailViewController
#synthesize PickerData, Picker, toolBar, backButton, barDoneButton, flexSpace;
- (void)viewDidLoad
{
[super viewDidLoad];
self.pickerData = #[#"Posture",#"Paludies Abbs",#"Custom"];
[self.delegate setCellName2:self.cellName];
toolBar = [[UIToolbar alloc] init];
toolBar.barStyle = UIBarStyleBlackOpaque;
[toolBar sizeToFit];
[toolBar setBackgroundImage:[UIImage imageNamed:#"red_navigation_bar.png"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:self
action:nil];
// Done button on toolbar
barDoneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(releasePicker)];
// Back button on toolbar
backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"style:UIBarButtonItemStyleDone
target:self
action:#selector(backToPicker)];
// Habit PickerView
Picker = [[UIPickerView alloc] init];
Picker.showsSelectionIndicator = YES;
Picker.delegate = self;
barDoneButton.image = [UIImage imageNamed:#"button.png"];
// Toolbar above picker
[toolBar setItems:#[flexSpace, barDoneButton] animated:YES];
self.habitField.inputAccessoryView = toolBar;
[self.habitField addTarget:self action:#selector(customHabitChanged) forControlEvents:UIControlEventEditingChanged];
[self.habitField setInputView:Picker];
}
- (void)customHabitChanged {
self.customHabit = self.habitField.text;
self.cellName = self.customHabit;
NSLog(#"%#", self.customHabit);
[self.delegate setCellName2:self.cellName];
}
- (void)backToPicker {
[toolBar setItems:#[flexSpace, barDoneButton] animated:YES];
[self.habitField resignFirstResponder];
[self.habitField setInputView:Picker];
[self.habitField becomeFirstResponder];
}
- (void)releasePicker {
[self.habitField resignFirstResponder];
[self.habitField setInputView:Picker];
[toolBar setItems:#[flexSpace, barDoneButton] animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)backToRoot:(id)sender {
[self.navigationController popToRootViewControllerAnimated:YES];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [PickerData count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [PickerData objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
[self.delegate setCellName2:self.PickerData[row]];
/* int select = row;
if (select == 0) {
self.cellName = #"Posture";
self.habitField.text = #"Posture";
[self.delegate setCellName2:self.cellName];
NSLog(#"%# Is Selected", self.cellName);
}
if (select == 1) {
self.cellName = #"Palaudies Abbs";
self.habitField.text = #"Palaudies Abbs";
[self.delegate setCellName2:self.cellName];
NSLog(#"%# Is Selected", self.cellName);
}
if (select == 2) {
[self.habitField resignFirstResponder];
[self.habitField setInputView:nil];
[self.habitField becomeFirstResponder];
[toolBar setItems:#[backButton, flexSpace, barDoneButton] animated:YES];
self.habitField.text = #"";
self.habitField.placeholder = #"Custom";
[self.delegate setCellName2:self.cellName];
NSLog(#"%# Is Selected", self.cellName);
*/ //}
}
IN cellForRowAtIndexPath
if(indexPath.row == object.count-1)
cell.textLabel.text = #"New Habit";
else
{
NSDate *object = _objects[indexPath.row];
cell.textLabel.text = [object description];
}
return cell;
Your thinking on this is not right. You shouldn't think in terms of setting the title of a cell, but instead think about updating the array that you use to populate the table view with data. Here is a simplified version of your app. When you click the add button it adds a new cell in row 0 with the label's text being "New Habit". When you click on that cell (or any other), it takes you to the controller with the picker view where you choose a string, and that string is passed back to the table view in a delegate method. In that method I update the array, myCells with that passed in string at the correct index gotten from the table's indexPathForSelectedRow, and then call reloadData on the table view to update it's view.
This is the table view controller:
#import "TableController.h"
#import "ViewController.h"
#interface TableController ()
#property (strong,nonatomic) NSMutableArray *myCells;
#end
#implementation TableController
- (IBAction)insertNewObject:(UIBarButtonItem *)sender
{
if (!self.myCells) {
self.myCells = [[NSMutableArray alloc] init];
}
[self.myCells insertObject:#"New Habit" atIndex:0];
NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[path] withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.myCells.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.myCells[indexPath.row];
return cell;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
ViewController *vc = segue.destinationViewController;
vc.delegate = self;
}
-(void)setCellName2:(NSString *)cellName {
NSInteger selectedRow = [self.tableView indexPathForSelectedRow].row;
[self.myCells replaceObjectAtIndex:selectedRow withObject:cellName];
[self.tableView reloadData];
}
Here is the controller (ViewController) with the picker view:
#interface ViewController ()
#property (strong,nonatomic) NSArray *pickerData;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.pickerData = #[#"Posture",#"Paludies Abbs",#"Custom"];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [self.pickerData count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [self.pickerData objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
[self.delegate setCellName2:self.pickerData[row]];
}
I have made an a Tabbed Bar Application in Xcode and the First Tab is Decors. I asked a previous question on integrating a XIB Project into a StoryBoard Tabbed Project.
I have Been Successfully in the integration of this, And it works but when I push on one of the Deocrs, Or Table Cells I get the following Error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[UIViewController _loadViewFromNibNamed:bundle:] loaded the "SelectedCellViewController" nib but the view outlet was not set.
If I put the Original Alert into my project The cell linking starts to work again.
Below are pics, links and code to my project, So you can see how it works
StoryBoard Project
XIB Project
DecorsViewController_iPhone.h
#import <UIKit/UIKit.h>
#interface DecorsViewController_iPhone : UIViewController
{
IBOutlet UITableView *tableViewDecors;
NSArray *sitesArray;
NSArray *imagesArray;
}
#property (nonatomic, retain) UITableView *tableViewDecors;
#property (nonatomic, retain) NSArray *sitesArray;
#property (nonatomic, retain) NSArray *imagesArray;
#end
DecorsViewController_iPhone.m
#import "DecorsViewController_iPhone.h"
#import "SelectedCellViewController.h"
#interface DecorsViewController_iPhone ()
#end
#implementation DecorsViewController_iPhone
#synthesize tableViewDecors;
#synthesize sitesArray;
#synthesize imagesArray;
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
// Load up the sitesArray with a dummy array : sites
NSArray *sites = [[NSArray alloc] initWithObjects:#"a", #"b", #"c", #"d", #"e", #"f", #"g", #"h", nil];
self.sitesArray = sites;
//[sites release];
UIImage *active = [UIImage imageNamed:#"a.png"];
UIImage *ae = [UIImage imageNamed:#"b.png"];
UIImage *audio = [UIImage imageNamed:#"c.png"];
UIImage *mobile = [UIImage imageNamed:#"d.png"];
UIImage *net = [UIImage imageNamed:#"e.png"];
UIImage *photo = [UIImage imageNamed:#"f.png"];
UIImage *psd = [UIImage imageNamed:#"g.png"];
UIImage *vector = [UIImage imageNamed:#"h.png"];
NSArray *images = [[NSArray alloc] initWithObjects: active, ae, audio, mobile, net, photo, psd, vector, nil];
self.imagesArray = images;
//[images release];
[super viewDidLoad];
}
#pragma mark - Table View datasource methods
// Required Methods
// Return the number of rows in a section
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
return [sitesArray count];
}
// Returns cell to render for each row
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure cell
NSUInteger row = [indexPath row];
// Sets the text for the cell
//cell.textLabel.text = [sitesArray objectAtIndex:row];
// Sets the imageview for the cell
cell.imageView.image = [imagesArray objectAtIndex:row];
// Sets the accessory for the cell
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Sets the detailtext for the cell (subtitle)
//cell.detailTextLabel.text = [NSString stringWithFormat:#"This is row: %i", row + 1];
return cell;
}
// Optional
// Returns the number of section in a table view
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
#pragma mark -
#pragma mark Table View delegate methods
// Return the height for each cell
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 78;
}
// Sets the title for header in the tableview
-(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return #"Decors";
}
// Sets the title for footer
-(NSString *) tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
return #"Decors";
}
// Sets the indentation for rows
-(NSInteger) tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath {
return 0;
}
// Method that gets called from the "Done" button (From the #selector in the line - [viewControllerToShow.navigationItem setRightBarButtonItem:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissView)] autorelease]];)
- (void)dismissView {
[self dismissViewControllerAnimated:YES completion:NULL];
}
// This method is run when the user taps the row in the tableview
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
SelectedCellViewController *viewControllerToShow = [[SelectedCellViewController alloc] initWithNibName:#"SelectedCellViewController" bundle:[NSBundle mainBundle]];
[viewControllerToShow setLabelText:[NSString stringWithFormat:#"You selected cell: %d - %#", indexPath.row, [sitesArray objectAtIndex:indexPath.row]]];
[viewControllerToShow setImage:(UIImage *)[imagesArray objectAtIndex:indexPath.row]];
[viewControllerToShow setModalPresentationStyle:UIModalPresentationFormSheet];
[viewControllerToShow setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[viewControllerToShow.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissView)]];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewControllerToShow];
viewControllerToShow = nil;
[self presentViewController:navController animated:YES completion:NULL];
navController = nil;
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Tapped row!"
// message:[NSString stringWithFormat:#"You tapped: %#", [sitesArray objectAtIndex:indexPath.row]]
// delegate:nil
// cancelButtonTitle:#"Yes, I did!"
// otherButtonTitles:nil];
// [alert show];
// [alert release];
}
#pragma mark - Memory management
- (void)didReceiveMemoryWarning {
NSLog(#"Memory Warning!");
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
self.sitesArray = nil;
self.imagesArray = nil;
[super viewDidUnload];
}
//- (void)dealloc {
//[sitesArray release];
//[imagesArray release];
// [super dealloc];
//}
#end
SelectedCellViewController.h
#interface SelectedCellViewController : UIViewController {
NSString *labelText;
UIImage *image;
IBOutlet UILabel *label;
IBOutlet UIImageView *imageView;
}
#property (nonatomic, copy) NSString *labelText;
#property (nonatomic, retain) UIImage *image;
#end
viewControllerToShow.m
#import "SelectedCellViewController.h"
#implementation SelectedCellViewController
#synthesize labelText;
#synthesize image;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
}
return self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
[label setText:self.labelText];
[imageView setImage:self.image];
}
- (void)viewDidUnload {
self.labelText = nil;
self.image = nil;
//[label release];
// [imageView release];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
check the class inherited by the "The controller to be shown on click".XIB in the identity inspector .It seems you have not set the class for the "to be shown" XIB and the view outlet of the same XIB.
I'm making my first app and I’m using XCode 4 with a Storyboard. Thanks to this place, lots of tutorials, Apple’s archives databases and a bit of me, I’m slowly getting the basics together. It’s an app populated from a plist. The plist is an array with dictionaries, the dictionarires containing stings with info about different red wines in Norway. First, the plist populates a TableView. I’m using NSSortDescritor to sort the TableView and added a button to the navigation bar for resorting if I want it displayed by another value. It looks like this:
RootTableViewController.h:
#import <UIKit/UIKit.h>
#interface RootTableViewController : UITableViewController <UIActionSheetDelegate> {
NSMutableArray *sortedObjects;
}
-(IBAction)sortButtonPressed:(id)sender;
#end
RootTableViewController.m:
#import "RootTableViewController.h"
#import "ObjectCell.h"
#import "DetailViewController.h"
#interface RootTableViewController ()
#end
#implementation RootTableViewController
- (IBAction)sortButtonPressed:(id)sender;
{
UIActionSheet *sort = [[UIActionSheet alloc]
//InitWithStyle etc for sheet
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSSortDescriptor *sortDesc;
if (buttonIndex == 0) {
sortDesc = [[NSSortDescriptor alloc] initWithKey:#"Name" ascending:YES];
[sortedWines sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
}
if (buttonIndex == 1) {
sortDesc = [[NSSortDescriptor alloc] initWithKey:#"Country" ascending:YES];
[sortedWines sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
}
[self.tableView reloadData];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *myfile = [[NSBundle mainBundle]
pathForResource:#"Objects" ofType:#"plist"];
sortedObjects = [[NSMutableArray alloc]initWithContentsOfFile:myfile];
NSSortDescriptor * sortDesc = [[NSSortDescriptor alloc] initWithKey:#"Popularity" ascending:YES];
[sortedObjects sortUsingDescriptors:[NSArray arrayWithObject:sortDesc]];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (void)viewWillAppear:(BOOL)animated {
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [sortedObjects count];
}
//(I’m using a Custom Cell for the TableView)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"objectCell";
ObjectCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[ObjectCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.nameLabel.text = [[sortedObjects objectAtIndex:indexPath.row] valueForKey:#"Name"];
cell.countryLabel.text = [[sortedObjects objectAtIndex:indexPath.row] valueForKey:#"Country"];
return cell;
}
#pragma mark - Table view delegate
//Then the selected object is sent to the DetailViewController in this segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"DetailSegue"]) {
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *detailViewController = [segue destinationViewController];
detailViewController.selectedObject = [sortedObjects objectAtIndex:selectedRowIndex.row];
}
}
#end
Then the DetailViewController recieves the selected object to populate the Labels and ImageViews with the data from it.
DetailViewController.h:
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController
#property (nonatomic, strong) IBOutlet UILabel *districtLabel;
#property (nonatomic, strong) IBOutlet UILabel *countryLabel;
#property (nonatomic, strong) IBOutlet UIImageView *bottleImageView;
#property (nonatomic, strong) NSString *selectedObject;
#end
DetailViewController.m:
#import "WinesDetailViewController.h"
#interface WinesDetailViewController ()
#end
#implementation WinesDetailViewController
#synthesize districtLabel,countryLabel,bottleImageView;
#synthesize selectedObject;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidAppear:(BOOL)animated
{
self.title = [selectedObject valueForKey:#"Name"];
[super viewDidAppear:animated];
}
- (void)viewDidLoad
{
[super viewDidLoad];
districtLabel.text = [selectedObject valueForKey:#"District"];
countryLabel.text = [selectedObject valueForKey:#"Country"];
bottleImageView.image = [UIImage imageNamed:[selectedObject valueForKey:#"Image"]];
self.navigationController.navigationBar.translucent = YES;
self.wantsFullScreenLayout = YES;
//Then I’ve added recognizers for left and right swiping:
UISwipeGestureRecognizer *leftGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeDetectedLeft:)];
leftGesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:leftGesture];
UISwipeGestureRecognizer *rightGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeDetectedRight:)];
rightGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:rightGesture];
}
//And the voids to handle the swipes:
- (void)swipeDetectedRight:(UISwipeGestureRecognizer *)sender
{
//Access previous cell in TableView
}
- (void)swipeDetectedLeft:(UISwipeGestureRecognizer *)sender
{
//Access next cell in TableView
}
//Some more besic code for the view..
#end
As you can see, I’ve added UISwipeGestureRecognizers in the DetailViewController, because I want to reload it with data from the previous cell to when swiped to the right, and next cell when swiped to the left. Now I have no idea how to handle the voids for swipe detected, how can I reach selectedRowIndex from DetailView and swipe through cells? I’m new to programming, have been trying to figure this out for a long time now, so code examples would be great so the answer don't lead to 100 new questions if you know what I mean. Thank you so much if you can help me.
One way to go about this is to pass the "sorted" datasource array to the DetailViewController and the indexpath through the "prepareForSegue" method.
RootTableViewController.h:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"DetailSegue"]) {
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *detailViewController = [segue destinationViewController];
detailViewController.selectedObject = [sortedObjects objectAtIndex:selectedRowIndex.row];
//added code
detailViewController.detailsDataSource = [[NSArray alloc]initWithArray:sortedObjects];
detailViewController.detailIndex = selectedRowIndex.row;
}
}
Then you could reload the UI elements of the DetailViewController.
Here is the declaration of the new properties.
DetailViewController.h:
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController
#property (nonatomic, strong) IBOutlet UILabel *districtLabel;
#property (nonatomic, strong) IBOutlet UILabel *countryLabel;
#property (nonatomic, strong) IBOutlet UIImageView *bottleImageView;
#property (nonatomic, strong) NSString *selectedObject;
// added code
#property (strong, nonatomic) NSArray *detailsDataSource;
#property int detailIndex;
#end
Don't forget to synthesize the new properties
#synthesize detailsDataSource,detailIndex;
//And the voids to handle the swipes:
- (void)swipeDetectedRight:(UISwipeGestureRecognizer *)sender
{
//Access previous cell in TableView
if (detailIndex != 0) // This way it will not go negative
detailIndex--;
districtLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"District"]];
countryLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"Country"];
bottleImageView.image = [UIImage imageNamed:[[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"Image"]];
}
- (void)swipeDetectedLeft:(UISwipeGestureRecognizer *)sender
{
//Access next cell in TableView
if (detailIndex != [detailsDataSource count]) // make sure that it does not go over the number of objects in the array.
detailIndex++; // you'll need to check bounds
districtLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"District"]];
countryLabel.text = [[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"Country"];
bottleImageView.image = [UIImage imageNamed:[[detailsDataSource objectAtIndex: detailIndex] valueForKey:#"Image"]];
}
//Some more besic code for the view..
#end
Give this a try it might work for you. Otherwise, I think you might want to take a look at Scrollview and "paging." iPhone/iPad users are used to this UI design, and you might be able to modify it to fit what you are doing.
I have a Card Object, which have 4 instance variables namely name(NSString), pin(NSString), points(NSNumber), pointsToDeduct(NSMutableArray).
Card.h
#interface Card : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *pin;
#property (nonatomic, strong) NSNumber *points;
#property (nonatomic, strong) NSMutableArray *pointsToDeduct;
#end
This pointsToDeduct array is always present for every new instance of Card I make. What I want is to fill it's values with another array's values which are static through a button click. But before that, in my code below, I cast those static values into an NSNumber so that the pointsToDeduct's values will be of type NSNumber. I'm thinking of delegation to do this though not sure if it's best. For now I want to access that pointsToDeduct array so I can add values in it.
*this is part of PerksDetailsViewController.m
- (IBAction)redeemPressed:(id)sender {
NSNumber *pointsRequired;
NSNumberFormatter * formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
pointsRequired = [formatter numberFromString: (self.pointsLabel.text)];
NSLog(#"points required by the perk %#", pointsRequired);
// now insert pointsRequired's value to pointsToDeduct array instance variable of a Card
Below are the other codes that I have.
Main View
CardWalletViewController.h
#import <UIKit/UIKit.h>
#interface CardWalletViewController : UITableViewController
#property (nonatomic, strong) NSMutableArray *myWallet;
-(void) printArrayContents;
CardWalletViewController.m
#import "CardWalletViewController.h"
#import "AddCardViewController.h"
#import "Card.h"
#import "CardDetailsViewController.h"
#interface CardWalletViewController () <AddCardDelegate>
#end
#implementation CardWalletViewController
#synthesize myWallet = _myWallet;
- (NSMutableArray *) myWallet
{
if (_myWallet == nil) _myWallet = [[NSMutableArray alloc] init];
return _myWallet;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showAddCardVC"]) {
AddCardViewController *addCardVC = (AddCardViewController *)segue.destinationViewController;
addCardVC.delegate = self;
}
}
- (void)printArrayContents
{
// I want to show the name of each instance
for ( int i = 0; i < self.myWallet.count; i++) {
Card *cardDummy = [self.myWallet objectAtIndex:i];
NSLog(#"Element %i is %#", i,cardDummy.name );
}
}
- (void)addCardViewController:(AddCardViewController *)sender didCreateCard:(Card *)newCard
{
// insert a new card to the array
[self.myWallet addObject:newCard];
[self printArrayContents];
[self.tableView reloadData];
}
- (void)saveMyWallet: (NSMutableArray *)myWallet
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:self.myWallet forKey:#"myWalletArray"];
[defaults synchronize];
NSLog(#"I am saved");
}
- (NSMutableArray *)loadWallet
{
NSMutableArray *boom;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
boom = [defaults objectForKey: #"myWalletArray"];
if (!boom) {
boom = [[NSMutableArray alloc] init];
}
return boom;
}
- (void)viewDidLoad
{
[self loadWallet];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
//this method will return the number of rows to be shown
return self.myWallet.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
Card *cardDummy = [self.myWallet objectAtIndex:indexPath.row];
cell.textLabel.text = cardDummy.name;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", cardDummy.points];
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//this method is responsible for showing the details of a selected card
//make another view controller - DetailVC perhaps
CardDetailsViewController *details = [self.storyboard instantiateViewControllerWithIdentifier:#"cardDetails"];
Card *cardDummy = [self.myWallet objectAtIndex:indexPath.row];
details.myPoints = [NSString stringWithFormat:#"%#", cardDummy.points];
[self.navigationController pushViewController:details animated:YES];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 60;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
The way I create a new Card
AddCardViewController.m
#import "AddCardViewController.h"
#import "Card.h"
#import "CardWalletViewController.h"
#interface AddCardViewController ()
#end
#implementation AddCardViewController
#synthesize cardNameTextField = _cardNameTextField;
#synthesize pinTextField = _pinTextField;
#synthesize pointsTextField = _pointsTextField;
#synthesize delegate = _delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.cardNameTextField becomeFirstResponder];
}
- (BOOL) textFieldShouldReturn:(UITextField *)textField{
if ([textField.text length]) {
[self.cardNameTextField resignFirstResponder];
[self.pinTextField resignFirstResponder];
[self.pointsTextField resignFirstResponder];
return YES;
}
else {
return NO;
}
}
- (void)viewDidLoad
{
self.cardNameTextField.delegate = self;
self.pinTextField.delegate = self;
self.pointsTextField.delegate = self;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setCardNameTextField:nil];
[self setPinTextField:nil];
[self setPointsTextField:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)addCard:(id)sender
{
Card *myNewCard = [[Card alloc] init];
myNewCard.name = self.cardNameTextField.text;
myNewCard.pin = self.pinTextField.text;
NSNumber *myPoints;
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
myPoints = [f numberFromString: (self.pointsTextField.text)];
myNewCard.points = myPoints;
//method here that will dismiss the modal view
// if condition forces the user to fill up all the text field
if ([self.cardNameTextField.text length] && [self.pinTextField.text length] && [self.pointsTextField.text length])
{
//method here that will dismiss the modal view
[[self presentingViewController] dismissModalViewControllerAnimated:YES];
//checking...
NSLog(#"name saved %#", myNewCard.name);
NSLog(#"pin saved %#", myNewCard.pin);
NSLog(#"points saved %#", myNewCard.points);
[self.delegate addCardViewController:self didCreateCard:myNewCard];
// to check if there is a delegate
/*
if (self.delegate){
NSLog(#"delegate is not nil");
}
*/
}
}
#end
AddCardViewController.h
#import <UIKit/UIKit.h>
#import "Card.h"
#class AddCardViewController;
#protocol AddCardDelegate <NSObject>
- (void)addCardViewController:(AddCardViewController *)sender
didCreateCard:(Card *) newCard;
#end
#interface AddCardViewController : UIViewController <UITextFieldDelegate>
#property (strong, nonatomic) IBOutlet UITextField *cardNameTextField;
#property (strong, nonatomic) IBOutlet UITextField *pinTextField;
#property (strong, nonatomic) IBOutlet UITextField *pointsTextField;
#property (nonatomic, strong) id <AddCardDelegate> delegate;
#end
CardDetailsViewController.m
#import "CardDetailsViewController.h"
#import "PerksDetailsViewController.h"
#import "Card.h"
#interface CardDetailsViewController ()
#end
#implementation CardDetailsViewController
#synthesize pointsLabel = _pointsLabel;
#synthesize myPoints = _myPoints;
#synthesize perks = _perks;
#synthesize datasource = _datasource;
#synthesize datasourcePoints = _datasourcePoints;
-(void)setupArray
{
self.perks = [[NSMutableDictionary alloc] init];
[self.perks setObject:#"200" forKey:#"10% Discount"];
[self.perks setObject:#"100" forKey:#"250Php Off"];
self.datasource = [self.perks allKeys]; //contains perk's description
self.datasourcePoints = [self.perks allValues]; //contains perk's required points
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 2;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [self.datasource objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [self.datasourcePoints objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
PerksDetailsViewController *perksDetails = [self.storyboard instantiateViewControllerWithIdentifier:#"detailsOfMyPerks"];
[self.navigationController pushViewController:perksDetails animated:YES];
perksDetails.perkDetailsLabel.text = [self.datasource objectAtIndex:indexPath.row];
perksDetails.pointsLabel.text = [self.perks objectForKey:perksDetails.perkDetailsLabel.text];
}
- (void)viewDidLoad
{
//show the number of points of the selected Card
self.pointsLabel.text = self.myPoints;
self.navigationItem.title = #"Your Points";
[self setupArray];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setPointsLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
#end
CardDetailsViewController.h
#import <UIKit/UIKit.h>
#interface CardDetailsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
}
#property (nonatomic, retain) NSMutableDictionary *perks;
#property (nonatomic, retain) NSArray *datasource;
#property (nonatomic, retain) NSArray *datasourcePoints;
-(void)setupArray;
#property (strong, nonatomic) IBOutlet UILabel *pointsLabel;
#property (nonatomic, weak) NSString *myPoints;
#end
PerksDetailsViewController.m
#import "PerksDetailsViewController.h"
#import "Card.h"
#import "CardWalletViewController.h"
#interface PerksDetailsViewController ()
#end
#implementation PerksDetailsViewController
#synthesize pointsLabel = _pointsLabel;
#synthesize perkDetailsLabel = _perkDetailsLabel;
#synthesize perkDetailText = _perkDetailText;
#synthesize pointsText = _pointsText;
- (IBAction)redeemPressed:(id)sender {
// get required points of a perk selected
// cast the NSString value to an int/NSInteger
NSNumber *pointsRequired;
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
pointsRequired = [f numberFromString: (self.pointsLabel.text)];
NSLog(#"points required by the perk %#", pointsRequired);
// now insert this value to points array instance variable of a Card
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
//self.perkDetailsLabel.text = self.perkDetailText;
//self.pointsLabel.text = self.pointsText;
NSLog(#"perk detail:%#", self.perkDetailText);
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setPerkDetailsLabel:nil];
[self setPointsLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
PerksDetailsViewController.h
#import <UIKit/UIKit.h>
#interface PerksDetailsViewController : UIViewController
{
NSString *perkDetailText;
NSString *pointsText;
IBOutlet UILabel *perkDetailsLabel;
IBOutlet UILabel *pointsLabel;
}
#property (nonatomic, retain) IBOutlet UILabel *perkDetailsLabel, *pointsLabel;
#property (nonatomic, retain) NSString *perkDetailText, *pointsText;
#end
Your PerksDetailViewController needs to have a property of the current Card object. Then, it's simply a matter of
[self.card.pointsToDeduct addObject:pointsRequired];
I can't see in all your sample code where you are actually using any Card objects.
in current class
NSMutable Array from One Class to Another Class in iPhone
#import "SecondViewController"
SecondViewController *NextViewController = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
NextViewController.nextClasssArray = thisClassarray;
in second class .h
#property(nonatomic,retain) NSMutableArray *nextClasssArray;
in second class .m
#synthesize nextClasssArray;
I have a fully operational web browser application that stores bookmarked pages. When the bookmarks button is clicked, a listview of the stored websites is displayed. Instead of showing the URL, I would like the listview to display the title of the page, but I would like the UIWebView to go to the URL when the title is clicked.
I have included the code below. I have also put the properties in both header files, but can't get it to work. Please help!
ExplorerViewController.h
#import <UIKit/UIKit.h>
#interface ExplorerViewController : UIViewController <UITextFieldDelegate, UIWebViewDelegate, UIActionSheetDelegate>{
UITextField *urlField;
UIBarButtonItem *refreshButton;
UIBarButtonItem *backButton;
UIBarButtonItem *forwardButton;
UIBarButtonItem *bookMarksButton;
UIActivityIndicatorView *loadingActivity;
UIWebView *webView;
UINavigationBar *navigationBar;
}
#property (nonatomic, retain) IBOutlet UITextField *urlField;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *refreshButton;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *backButton;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *forwardButton;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *bookMarksButton;
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView *loadingActivity;
#property (nonatomic, retain) IBOutlet UIWebView *webView;
#property (nonatomic, retain) IBOutlet UINavigationBar *navigationBar;
-(NSString*)repairURL:(NSString*)url;
-(IBAction)refreshWebView;
-(IBAction)goBack;
-(IBAction)goForward;
-(void)actualizeButtons;
-(IBAction)bookmarksButtonTapped;
-(IBAction)addBookmarkButtonTapped;
#end
ExplorerViewController.m
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSMutableArray *bookmarks = [[[NSUserDefaults standardUserDefaults] arrayForKey:#"Bookmarks"] mutableCopy];
NSMutableArray *websitetitle = [[[NSUserDefaults standardUserDefaults] arrayForKey:#"Websitetitle"] mutableCopy];
if (!bookmarks) {
bookmarks = [[NSMutableArray alloc] init];
}
[bookmarks addObject:[[[[self webView]request] URL] absoluteString]];
[websitetitle addObject:[self.webView stringByEvaluatingJavaScriptFromString:#"document.title"]];
[[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:#"Bookmarks"];
[[NSUserDefaults standardUserDefaults] setObject:websitetitle forKey:#"Websitetitle"];
[bookmarks release];
[websitetitle release];
}
}
BookmarksViewController.h
#import <UIKit/UIKit.h>
#class ExplorerViewController;
#interface BookmarksViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>{
NSMutableArray *bookmarks;
NSMutableArray *websitetitle;
ExplorerViewController *explorerView;
}
#property (nonatomic, retain) NSMutableArray *bookmarks;
#property (nonatomic, retain) NSMutableArray *websitetitle;
#property (nonatomic, retain) ExplorerViewController *explorerView;
-(IBAction)cancelButtonTapped;
#end
BookmarksViewController.m
#import "BookmarksViewController.h"
#import "ExplorerViewController.h"
#implementation BookmarksViewController
#synthesize bookmarks, websitetitle, explorerView;
-(IBAction)cancelButtonTapped {
[self.parentViewController dismissModalViewControllerAnimated:true];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [bookmarks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellIdentifier] autorelease];
}
cell.textLabel.text = [websitetitle objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
explorerView.urlField.text = [bookmarks objectAtIndex:indexPath.row];
[explorerView textFieldShouldReturn:explorerView.urlField];
[self.parentViewController dismissModalViewControllerAnimated:true];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[bookmarks removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];
[[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:#"Bookmarks"];
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
// e.g. self.myOutlet = nil;
[explorerView release];
explorerView = nil;
[bookmarks release];
bookmarks = nil;
}
You have to implement tableView:didSelectRowAtIndexPath:, roughly as follows:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *url=[bookmarks objectAtIndex:indexPath.row];
// open url here
}
A few considerations about your code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
explorerView.urlField.text = [bookmarks objectAtIndex:indexPath.row];
[explorerView textFieldShouldReturn:explorerView.urlField];
[self.parentViewController dismissModalViewControllerAnimated:true];
}
are you trying to replicate Mobile Safari?
you should probably avoid storing your bookmarks in the NSUserDefaults storage, and use a proper store.
you should not attempt to trigger a navigation action by simulating interaction events; the proper way to make a UIWebView (your underlying browser object) load a webpage is by using loadRequest:
The following code might work for you (I am relying on a lot of assumptions here):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Get your url from the bookmarks object
NSString *urlString = [bookmarks objectAtIndex:indexPath.row];
// Convert to a URL object.
NSURL *url = [NSURL URLWithString:urlString];
// Create request
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[explorerView.webView loadRequest:requestObj];
// dismiss
[self.parentViewController dismissModalViewControllerAnimated:true];
}