Pass Tableview cell's text to RootViewController - ios

I am newbie in iOS programming. I have read so may threads regarding this problem but also couldn't figure out what is actually causing the error. I need to pass first tableview cell's text of tableview of bookmarkViewController back to URL address bar of myViewController which is the root ViewController when i click the first tableview's cell.
Everything is working fine beside this data passing to root ViewController and i am using delegation for it.
myViewController.h
#import "bookmarkViewController.h"
#import <UIKit/UIKit.h>
#import "historyViewController.h"
#import "AppDelegate.h"
#import "Reachability.h"
#interface myViewController : UIViewController <UITextFieldDelegate,UIAlertViewDelegate,secondViewControllerDelegate>
#property (weak, nonatomic) IBOutlet UIBarButtonItem *addButton;
#property (weak, nonatomic) IBOutlet UITextField *addressBar;
#property (weak, nonatomic) IBOutlet UIWebView *webView;
#property (weak, nonatomic) IBOutlet UITextField *searchBar;
- (IBAction)goBack:(id)sender;
- (IBAction)goForward:(id)sender;
- (IBAction)refreshWebView:(id)sender;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *goBackButton;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *goForwardButton;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *refreshButton;
-(void)textFieldDidEndEditing:(UITextField *)textField;
- (void) loadWebPageFromString:(NSString *)string;
#end
myViewController.m
#import "myViewController.h"
#interface myViewController ()
#end
#implementation myViewController
-(void)loadView
{
[super loadView];
[_goBackButton setEnabled:NO];
}
- (void)webViewDidFinishLoad:(UIWebView *)webview
{
_addButton.enabled=YES;
_refreshButton.enabled=YES;
if ([_webView canGoBack]) {
[_goBackButton setEnabled:YES];
} else [_goBackButton setEnabled:NO];
if ([_webView canGoForward]) {
[_goForwardButton setEnabled:YES];
} else _goForwardButton.enabled=NO;
}
- (void)checkForWIFIConnection {
Reachability* wifiReach = [Reachability reachabilityForLocalWiFi];
NetworkStatus netStatus = [wifiReach currentReachabilityStatus];
if (netStatus!=ReachableViaWiFi)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Internet Connection"
message:#"Your device is not connected to internet."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
- (void)viewDidLoad
{
_refreshButton.enabled=NO;
_addButton.enabled=NO;
[_goBackButton setEnabled:NO];
_goForwardButton.enabled=NO;
[self checkForWIFIConnection];
[super viewDidLoad];
}
-(void)textFieldDidEndEditing :(UITextField *)textField
{
if (textField.text){
if (textField==_searchBar){
AppDelegate *historydelegate= (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSMutableArray *a=historydelegate.historyArray;
NSString *b=[NSString stringWithFormat:#"http://www.google.com/search?q=%#",textField.text] ;
[a addObject:b];
}}}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)googleEntered:(UITextField *)sender {
Reachability* wifiReach = [Reachability reachabilityForLocalWiFi];
NetworkStatus netStatus = [wifiReach currentReachabilityStatus];
if (netStatus==ReachableViaWiFi){
[self loadWebPageFromString:_searchBar.text];
[self textFieldDidEndEditing:_searchBar];
_addressBar.text=[NSString stringWithFormat: #"http://www.google.com/search?q=%#",_searchBar.text] ;
}else {[self checkForWIFIConnection];self.addressBar.text=NULL;}
}
- (IBAction)goBack:(id)sender {
[_webView goBack];
_searchBar.text=NULL;
_addressBar.text=NULL;
}
- (IBAction)goForward:(id)sender {
[_webView goForward];
_searchBar.text=NULL;
}
- (IBAction)refreshWebView:(id)sender {
[_webView reload];
[self checkForWIFIConnection];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
AppDelegate *maindelegate= (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSMutableArray *a=maindelegate.bookmarksArray;
if([segue.identifier isEqualToString:#"segueOne"]){
if ([_addressBar.text length]!=0){
NSString *b=[NSString stringWithFormat:#"%#",_addressBar.text];
[a addObject:b];
}}}
- (void) loadWebPageFromString:(NSString *)string {
NSURL *url = [NSURL URLWithString:string];
NSString *googleSearch = [string stringByReplacingOccurrencesOfString:#" " withString:#"+"];
url = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.google.com/search?q=%#", googleSearch]];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
[_webView loadRequest:request];
}
-(void)loadAddress:(NSString *)mystring{
NSURL *myurl = [NSURL URLWithString:mystring];
if(!myurl.scheme){
myurl = [NSURL URLWithString:[NSString stringWithFormat:#"http://%#", mystring]];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:myurl];
[_webView loadRequest:request];}
else{
myurl = [NSURL URLWithString:[NSString stringWithFormat:#"%#", mystring]];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:myurl];
[_webView loadRequest:request];
}
}
-(BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
if (navigationType==UIWebViewNavigationTypeLinkClicked) {
NSURL *URL=[request URL];
[self checkForWIFIConnection];
if ([URL scheme] ) {
Reachability* wifiReach = [Reachability reachabilityForLocalWiFi];
NetworkStatus netStatus = [wifiReach currentReachabilityStatus];
if (netStatus==ReachableViaWiFi ){
_addressBar.text=URL.absoluteString;
_searchBar.text=NULL;
[_webView loadRequest:request];
AppDelegate *historydelegate= (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSMutableArray *a=historydelegate.historyArray;
[a addObject:URL.absoluteString];
}
}
return NO;
}
return YES;
}
- (BOOL) urlIsValid: (NSString *) url
{
NSString *regex =
#"((?:http|https)://)?(?:www\\.)?[\\w\\d\\-_]+\\.\\w{2,3}(\\.\\w{2})?(/(?<=/)(?:[\\w\\d\\-./_]+)?)?";
/// OR use this
///NSString *regex = "(http|ftp|https)://[\w-_]+(.[\w-_]+)+([\w-.,#?^=%&:/~+#]* [\w-\#?^=%&/~+#])?";
NSPredicate *regextest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", regex];
if ([regextest evaluateWithObject: url] == NO) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Invalid URL"
message:#"Enter valid URL."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
return [regextest evaluateWithObject:url];
}
-(IBAction)addressEntered:(UITextField *)sender {
Reachability* wifiReach = [Reachability reachabilityForLocalWiFi];
NetworkStatus netStatus = [wifiReach currentReachabilityStatus];
if (netStatus==ReachableViaWiFi && [self urlIsValid:_addressBar.text]){
[self loadAddress:_addressBar.text];
AppDelegate *historydelegate= (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSMutableArray *a=historydelegate.historyArray;
[a addObject:_addressBar.text];
}else [self checkForWIFIConnection];
[sender resignFirstResponder];
_searchBar.text =NULL;
}
-(void)showView{
bookmarkViewController *b=[[bookmarkViewController alloc]initWithNibName:#"bookmarkViewController" bundle:nil];
b.delegate=self;
[self presentViewController:b animated:YES completion:nil];
}
- (void)passData:(NSString *)data
{
self.addressBar.text=data;
}
- (IBAction)go:(id)sender {
[self showView];
}
#end
bookmarkViewController.h
#protocol secondViewControllerDelegate <NSObject>
#required
- (void)passData:(NSString *)data;
#end
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "myViewController.h"
#interface bookmarkViewController : UIViewController
#property (nonatomic, weak) id<secondViewControllerDelegate> delegate;
#property (weak, nonatomic) IBOutlet UITableView *tableView;
- (IBAction)goBac:(id)sender;
#end
bookmarkViewController.m
#import "bookmarkViewController.h"
#import "AppDelegate.h"
#interface bookmarkViewController ()
#end
#implementation bookmarkViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (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];
}
// Configure the cell...
AppDelegate *maindelegate= (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSMutableArray *a=[maindelegate bookmarksArray];
cell.textLabel.text = [a objectAtIndex:[indexPath row]];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
if ([indexPath row]==0) {
if ([self.delegate respondsToSelector:#selector(passData:)]) {
[self.delegate passData:cell.textLabel.text];
}
[self dismissViewControllerAnimated:YES completion:nil];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
AppDelegate *maindelegate= (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSMutableArray *a=[maindelegate bookmarksArray];
return [a count];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[self tableView] reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)goBac:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end

You shouldn't use dequeueReusableCellWithIdentifier: method when a row is selected. It should be used only when you want to get a reusable cell actually. You can use:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
if ([indexPath row]==0)
{
if ([self.delegate respondsToSelector:#selector(passData:)])
{
[self.delegate passData:cell.textLabel.text];
}
}
}
You shouldn't call dismissViewControllerAnimated:completion: method from your child view controller, it is the parent view controller's job.
And in your delegate method:
- (void) passData:(NSString *)data
{
self.addressBar.text = data;
[self dismissViewControllerAnimated:YES completion:nil];
}
EDIT: Method names updated.

Another way to do same is by using navigation controller stack if your application is navigation based.
Try this:-
1.Define a global NSString in MyViewController.h like
#property(strong, nonatomic) NSString *strText;
2.Do following code on didSelectRowAtIndexPath of BookMarkViewController
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
if(indexPath.row == 0)
{
NSArray *arrControllers = [self.navigationController.viewControllers];
MyViewController *objMyCnrl = [arrControllers objectAtIndex:[arrControllers count]-2];
objMyCnrl.strText = cell.textLabel.text; // Pass the string value here
[self dismissViewControllerAnimated:YES completion:nil];
}
}

Related

ViewController not properly sending over NSURL data to Destination ViewController

When a user taps a cell, I want itemURL to be set to that cells "Item URL" property. Once it does this, it should then send over the itemURL in prepareForSegue over to WebViewController, as I've attempted to do. When I have WebViewController NSLog the itemURL property however, it comes up as null. How can I make sure the value is sent over properly?
MatchCenterViewController.h:
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import "AsyncImageView.h"
#import "SearchViewController.h"
#import "WebViewController.h"
#interface MatchCenterViewController : UIViewController <UITableViewDataSource>
#property (nonatomic) IBOutlet NSString *itemSearch;
#property (nonatomic, strong) NSArray *imageURLs;
#property (strong, nonatomic) NSString *matchingCategoryCondition;
#property (strong, nonatomic) NSString *matchingCategoryLocation;
#property (strong, nonatomic) NSNumber *matchingCategoryMaxPrice;
#property (strong, nonatomic) NSNumber *matchingCategoryMinPrice;
#property (strong, nonatomic) NSArray *matchCenterArray;
#property (strong, nonatomic) NSString *searchTerm;
#property (strong, nonatomic) NSURL *itemURL;
#end
MatchCenterViewController.m:
#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>
#interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UITableView *matchCenter;
#end
#implementation MatchCenterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewCellStyleSubtitle];
self.matchCenter.frame = CGRectMake(0,50,320,self.view.frame.size.height-100);
_matchCenter.dataSource = self;
_matchCenter.delegate = self;
[self.view addSubview:self.matchCenter];
_matchCenterArray = [[NSArray alloc] init];
}
- (void)viewDidAppear:(BOOL)animated
{
self.matchCenterArray = [[NSArray alloc] init];
[PFCloud callFunctionInBackground:#"MatchCenter"
withParameters:#{
#"test": #"Hi",
}
block:^(NSArray *result, NSError *error) {
if (!error) {
_matchCenterArray = result;
[_matchCenter reloadData];
NSLog(#"Result: '%#'", result);
}
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return _matchCenterArray.count;
}
//the part where i setup sections and the deleting of said sections
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 21.0f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 21)];
headerView.backgroundColor = [UIColor lightGrayColor];
_searchTerm = [[[[_matchCenterArray objectAtIndex:section] objectForKey:#"Top 3"] objectAtIndex:3]objectForKey:#"Search Term"];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(8, 0, 250, 21)];
headerLabel.text = [NSString stringWithFormat:#"%#", _searchTerm];
headerLabel.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
headerLabel.textColor = [UIColor whiteColor];
headerLabel.backgroundColor = [UIColor lightGrayColor];
[headerView addSubview:headerLabel];
UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
deleteButton.tag = section;
deleteButton.frame = CGRectMake(300, 2, 17, 17);
[deleteButton setImage:[UIImage imageNamed:#"xbutton.png"] forState:UIControlStateNormal];
[deleteButton addTarget:self action:#selector(deleteButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[headerView addSubview:deleteButton];
return headerView;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Initialize cell
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
// if no cell could be dequeued create a new one
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// No cell seperators = clean design
tableView.separatorColor = [UIColor clearColor];
// title of the item
cell.textLabel.text = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Title"];
cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
// price of the item
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#", _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Price"]];
cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0f green:127/255.0f blue:31/255.0f alpha:1.0f];
// image of the item
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:_matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Image URL"]]];
[[cell imageView] setImage:[UIImage imageWithData:imageData]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 65;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURL *itemURL = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Item URL"];
// NSLog(#"The url is: '%#'", itemURL);
[self performSegueWithIdentifier:#"WebViewSegue" sender:self];
}
- (void)deleteButtonPressed:(id)sender
{
// links button
UIButton *deleteButton = (UIButton *)sender;
// Define the sections title
NSString *sectionName = _searchTerm = [[[[_matchCenterArray objectAtIndex:deleteButton.tag] objectForKey:#"Top 3"] objectAtIndex:3]objectForKey:#"Search Term"];
// Run delete function with respective section header as parameter
[PFCloud callFunctionInBackground:#"deleteFromMatchCenter"
withParameters:
#{#"searchTerm": sectionName,}
block:^(NSDictionary *result, NSError *error) {
if (!error) {
[PFCloud callFunctionInBackground:#"MatchCenter"
withParameters:#{
#"test": #"Hi",
}
block:^(NSArray *result, NSError *error) {
if (!error) {
_matchCenterArray = result;
[_matchCenter reloadData];
NSLog(#"Result: '%#'", result);
}
}];
}
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
WebViewController *controller = (WebViewController *) segue.destinationViewController;
controller.itemURL = self.itemURL;
}
#end
WebViewController.h:
#import <UIKit/UIKit.h>
#import "MatchCenterViewController.h"
#interface WebViewController : UIViewController <UIWebViewDelegate>
#property (strong, nonatomic) NSURL *itemURL;
#property (weak, nonatomic) IBOutlet UIWebView *myWebView;
#end
WebViewController.m:
#import "WebViewController.h"
#interface WebViewController ()
#end
#implementation WebViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"The url is: '%#'", _itemURL);
// _myWebView=[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
// _myWebView.delegate=self;
// [self.view addSubview:_myWebView];
self.myWebView.delegate = self;
//////////
NSURLRequest *request = [NSURLRequest requestWithURL:_itemURL];
//4
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//5
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if ([data length] > 0 && error == nil) [self.myWebView loadRequest:request];
else if (error != nil) NSLog(#"Error: %#", error);
}];
[self.myWebView setScalesPageToFit:YES];
//////
//[self.myWebView loadRequest:request];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
In your didSelectRowForIndexPath: instead of
NSURL *itemURL = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Item URL"];
use
self.itemURL = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Item URL"];

website not loading in UIWebView

I've set my code up so that when a user taps a cell in the UITableView, it segues to WebViewController, and passes that cells "Item URL" property along the way. In the WebViewController class, I initialize a UIWebView, and have it load the respective URL. For some reason, it shows up blank and doesn't do any loading. How can I set my WebViewController to begin loading the webpage once it segues over?
WebViewController.h:
#import <UIKit/UIKit.h>
#import "MatchCenterViewController.h"
#interface WebViewController : UIViewController <UIWebViewDelegate>
#property (strong, nonatomic) NSURL *itemURL;
#property (strong, nonatomic) IBOutlet UIWebView *myWebView;
#end
WebViewController.m:
#import "WebViewController.h"
#interface WebViewController ()
#end
#implementation WebViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_myWebView=[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
_myWebView.delegate=self;
[self.view addSubview:_myWebView];
self.myWebView.delegate = self; //set the delegate first before calling LoadRequest
NSURL *url = [NSURL URLWithString:_itemURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.myWebView setScalesPageToFit:YES];
[self.myWebView loadRequest:request];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
MatchCenterViewController.h:
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import "AsyncImageView.h"
#import "SearchViewController.h"
#import "WebViewController.h"
#interface MatchCenterViewController : UIViewController <UITableViewDataSource>
//irrelevant code hidden for conciseness
#property (strong, nonatomic) NSArray *matchCenterArray;
#property (strong, nonatomic) NSString *searchTerm;
#property (strong, nonatomic) NSURL *itemURL;
#end
MatchCenterViewController.m:
#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>
#interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UITableView *matchCenter;
#end
#implementation MatchCenterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewCellStyleSubtitle];
self.matchCenter.frame = CGRectMake(0,50,320,self.view.frame.size.height-100);
_matchCenter.dataSource = self;
_matchCenter.delegate = self;
[self.view addSubview:self.matchCenter];
_matchCenterArray = [[NSArray alloc] init];
}
- (void)viewDidAppear:(BOOL)animated
{
self.matchCenterArray = [[NSArray alloc] init];
[PFCloud callFunctionInBackground:#"MatchCenter"
withParameters:#{
#"test": #"Hi",
}
block:^(NSArray *result, NSError *error) {
if (!error) {
_matchCenterArray = result;
[_matchCenter reloadData];
NSLog(#"Result: '%#'", result);
}
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return _matchCenterArray.count;
}
//the part where i setup sections and the deleting of said sections
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 21.0f;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
//irrelevant code removed for conciseness
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Initialize cell
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
// if no cell could be dequeued create a new one
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
//irrelevant code removed for conciseness
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 65;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURL *itemURL = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Item URL"];
[self performSegueWithIdentifier:#"WebViewSegue" sender:self];
}
- (void)deleteButtonPressed:(id)sender
{
// links button
UIButton *deleteButton = (UIButton *)sender;
// Define the sections title
NSString *sectionName = _searchTerm = [[[[_matchCenterArray objectAtIndex:deleteButton.tag] objectForKey:#"Top 3"] objectAtIndex:3]objectForKey:#"Search Term"];
// Run delete function with respective section header as parameter
[PFCloud callFunctionInBackground:#"deleteFromMatchCenter"
withParameters:
#{#"searchTerm": sectionName,}
block:^(NSDictionary *result, NSError *error) {
if (!error) {
[PFCloud callFunctionInBackground:#"MatchCenter"
withParameters:#{
#"test": #"Hi",
}
block:^(NSArray *result, NSError *error) {
if (!error) {
_matchCenterArray = result;
[_matchCenter reloadData];
NSLog(#"Result: '%#'", result);
}
}];
}
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
WebViewController *controller = (WebViewController *) segue.destinationViewController;
controller.itemURL = self.itemURL;
}
#end
This line in your code indicates that you have a WebView in your Xib file and you have an outlet attached to it:
#property (strong, nonatomic) IBOutlet UIWebView *myWebView;
So When you already have a webView defined in your Xib file, why are you creating another UIWebView and assigning it to the IBOutlet's webView? There is no point in allocating a new webView and adding it as subview. That is, you should discard these lines:
_myWebView=[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
_myWebView.delegate=self;
[self.view addSubview:_myWebView];
The reason is that when you already have a WebView in Xib file then you don't need another instance of it. Simply do:
self.myWebView.delegate = self;
NSURL *url = [NSURL URLWithString: itemURL]; //itemURL must be a NSString. If it is a NSURL, then you should skip this line and put itemURL in the next line instead of "url"
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.myWebView setScalesPageToFit:YES];
[self.myWebView loadRequest:request];
There's a bug in your code:
NSURL *url = [NSURL URLWithString:_itemURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
_itemURL is an NSURL object, not a NSString. You should just be able to do
NSURLRequest *request = [NSURLRequest requestWithURL:_itemURL];
provided _itemURL is set.
In the viewDidLoad method of your WebViewController, add this code:
-(void)viewDidLoad {
[super viewDidLoad];
UIWebView* webView = [UIWebView alloc] initWithFrame:self.view.frame];
[self.view addSubView:webView];
NSURLRequest* request = [NSURLRequest requestWithURL:self.itemURL; cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30];
[webView loadRequest:request];
}

Can't get a tableviewcontroller to reload after adding a new element

So I've been trying this for a while now and it is completely frustrating me but here is a brief summary of what I am trying to do. I have a LocationTableViewController with a plus button on the top right to add new locations to the table view. When that happens, I enter the LocationEditViewController where I can enter the name of the location I want to add. After adding my text and hitting the save location button I want the code to bring me back to the LocationTableViewController and there in my table I see my newly added location. Posted below is the code of the two view controllers. Hopefully you guys can help me thanks a ton!!
#import <UIKit/UIKit.h>
#import "Location.h"
#import "User.h"
#interface LocationEditViewController : UIViewController <UITextFieldDelegate>
#property (strong, nonatomic) Location *location;
#property (strong, nonatomic) User *user;
#property (strong, nonatomic) UITextField *locationNameField;
- (void)saveLocation:(id) sender;
#end
#import "LocationEditViewController.h"
#interface LocationEditViewController ()
#end
#implementation LocationEditViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = #"Edit";
self.location = [[Location alloc] init];
self.user = [[User alloc] init];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UILabel *locationLabel = [[UILabel alloc] init];
locationLabel.frame = CGRectMake(20,15,50,30);
locationLabel.text = #"Name:";
[self.view addSubview:locationLabel];
self.locationNameField = [[UITextField alloc] init];
self.locationNameField.frame = CGRectMake(15,50,290,30);
self.locationNameField.borderStyle = UITextBorderStyleBezel;
self.locationNameField.keyboardType = UIKeyboardTypeDefault;
self.locationNameField.delegate = self;
[self.view addSubview:self.locationNameField];
UIButton *saveLocationButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
saveLocationButton.frame = CGRectMake(15,400,290,50);
[saveLocationButton setTitle:#"Save Location" forState:UIControlStateNormal];
[saveLocationButton addTarget:self action:#selector(saveLocation:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:saveLocationButton];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)saveLocation:(id)sender {
self.location.name = self.locationNameField.text;
NSMutableArray *tempArray = [[NSMutableArray alloc] initWithArray:self.user.createdLocations];
[tempArray addObject:self.location];
self.user.createdLocations = [[NSArray alloc] initWithArray:tempArray];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Location Added"
message:#"This location is now accessable in the locations tab"
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alert show];
[self.tabBarController.tabBar.items[1] setBadgeValue:[NSString stringWithFormat:#"%i",self.user.createdLocations.count]];
[self dismissViewControllerAnimated:YES completion:^{
[[NSNotificationCenter defaultCenter] postNotificationName:#"somethingAddedNotification" object:nil];
}];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
Here is the LocationTableViewController code:
#import <UIKit/UIKit.h>
#import "User.h"
#interface LocationTableViewController : UITableViewController
#property (strong, nonatomic) NSArray *locations;
#property (strong, nonatomic) User *user;
#property (strong, nonatomic) id _observer;
- (void) addLocationPressed;
#end
#import "LocationTableViewController.h"
#import "LocationEditViewController.h"
#import "LocationViewController.h"
#interface LocationTableViewController ()
#end
#implementation LocationTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
self.title = #"Locations";
self.user = [[User alloc] init];
UIBarButtonItem *addLocationButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addLocationPressed)];
self.navigationItem.rightBarButtonItem = addLocationButton;
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//Location *loc = [[Location alloc] init];
//self.user.createdLocations = #[loc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void) addLocationPressed
{
LocationEditViewController *locationEditVC = [[LocationEditViewController alloc] init];
[self presentViewController:locationEditVC animated:YES completion:nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.user.createdLocations.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
cell.textLabel.text = [self.user.createdLocations[indexPath.row] name];
NSLog(#"%#", [self.user.createdLocations[indexPath.row] name]);
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
LocationViewController *locationVC = [[LocationViewController alloc] init];
locationVC.location = self.user.createdLocations[indexPath.row];
[self.navigationController pushViewController:locationVC animated:YES];
}
- (void)viewWillAppear:(BOOL)animated {
__observer = [[NSNotificationCenter defaultCenter] addObserverForName:#"somethingAddedNotification"
object:nil
queue:nil
usingBlock:^(NSNotification *notification)
{
[self.tableView reloadData];
}];
}
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:__observer];
}
For additional information here is the user class where I am getting the array
#import <Foundation/Foundation.h>
#import "Location.h"
#interface User : NSObject
#property (strong, nonatomic) Location *profilePhoto;
#property (strong, nonatomic) NSString *location;
#property (strong, nonatomic) NSArray *createdLocations;
-(id) initWithTitle: (Location *) aLoc
detail: (NSString *) aDet
filename: (NSArray *) aLocList;
//-(id)initWithJSON;
//+(NSString *)getPathToArchive;
//+(User *)getUser;
//+(void)saveUser:(User *)aUser;
#end
#import "User.h"
#import "Location.h"
#implementation User
- (id)init;
{
self = [self initWithTitle: [[Location alloc] init]
detail: #"Temp"
filename: [[NSArray alloc] init]];
return self;
}
-(id) initWithTitle: (Location *) aLoc
detail: (NSString *) aDet
filename: (NSArray *) aLocList
{
self = [super init];
if (self) {
self.profilePhoto = aLoc;
self.location = aDet;
self.createdLocations = aLocList;
}
return self;
}
#end
and the Locations class if necessary
#import <Foundation/Foundation.h>
#interface Location : NSObject
#property (strong, nonatomic) NSString *name;
#property (strong, nonatomic) NSString *detail;
#property (strong, nonatomic) NSString *filename;
#property (strong, nonatomic) NSString *thumbnail;
-(id) initWithTitle: (NSString *) aTitle
detail: (NSString *) aDetail
filename: (NSString *) aFilename
thumbnail: (NSString *) aThumbnail;
#end
#import "Location.h"
#implementation Location
-(id)init
{
self = [self initWithTitle:#"Title"
detail:#"Detail"
filename:#"placeholder.jpg"
thumbnail:#"placeholder.jpg"];
return self;
}
-(id)initWithTitle:(NSString *)aTitle
detail:(NSString *)aDetail
filename:(NSString *)aFilename
thumbnail:(NSString *)aThumbnail
{
self = [super init];
if (self) {
self.name = aTitle;
self.detail = aDetail;
self.filename = aFilename;
self.thumbnail = aThumbnail;
}
return self;
}
#end
Hopefully you guys can help me! Thanks again!!!
Have you set a breakpoint on...
[self.tableView reloadData];
...in your observer block? Does it get hit? Separately, Drew Crawford is wary of that API you are using (http://sealedabstract.com/code/nsnotificationcenter-with-blocks-considered-harmful/).
Like the comment said, this is definitely a problem, and may in fact be the root cause. You must use the __weak reference inside the block or else NSNotificationCenter owns a strong reference to self and self owns a strong reference to NSNotificationCenter, and you have a retain cycle.
- (void)viewWillAppear:(BOOL)animated {
__weak LocationTableViewController *weakSelf = self;
__observer = [[NSNotificationCenter defaultCenter] addObserverForName:#"somethingAddedNotification"
object:nil
queue:nil
usingBlock:^(NSNotification *notification)
{
[weakSelf.tableView reloadData];
}];
}

vanished self.delegate in arc: EXC_BAD_ACCESS

I have a SurroundViewController (CollectionView) which shows images loaded from a webserver. If you click on the image you will be navigated to a DetailViewController (TableView) which shows additional information to the image. Both Emebded in a NavigationController (see storyboard image).
My problem start when I do a refresh in the SurroundViewController, when coming back from the DetailViewController. Then it crashes with EXC_BAD_ACCESS on the performSelector line
WebApi.m
-(void)getSurroundStream {
NSString *URLString = [NSString stringWithFormat:#"%#/%#/view/%f/%f", kApiHost, kApiPath, self.sshare.coordinate.longitude, self.sshare.coordinate.latitude];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[self setAuthHeader:manager];
[manager GET:URLString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
[self.sshare putViData:responseObject];
[self.delegate performSelector:#selector(didLoadFoo)]; // --> EXC_BAD_ACCESS
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[self.error vError:error message:operation.responseString url:URLString];
}];
}
I checked in the Debug Console:
2014-03-11 14:22:51.989 Foo[6923:60b] -[SurroundViewController refresh:] [Line 352] refreshing
2014-03-11 14:22:51.998 Foo[6923:60b] -[WebApi getSurroundImages] [Line 393] do surround composition
(lldb) po self.delegate
[no Objective-C description available]
Seems that the object which is not available. What I do not understand is. I am in the SurroundViewController and do activly a refresh by pull-to-refresh. So I am on the Surround View and the object should be available...
How do I fix this issue, that the App does not crash with EXC_BAD_ACCESS at the performSelector line?
Here's the code which is involved with the issue (necessary parts):
SurroundViewController.h
#import <UIKit/UIKit.h>
#import "WebApi.h"
#import "DetailViewController.h"
#import "SingletonClass.h"
#interface SurroundViewController : UICollectionViewController <WebApiDelegate>
#property (nonatomic, strong) WebApi *swebapi;
#property (nonatomic, strong) SingletonClass *sshare;
#end
SurroundViewController.m
#import "SurroundViewController.h"
#interface SurroundViewController ()
#property (nonatomic, strong) UIRefreshControl *refresh;
#end
#implementation SurroundViewController
-(void)vinit {
self.sshare = [SingletonClass sharedInstance];
self.swebapi = [WebApi sharedInstance];
self.swebapi.delegate = self;
}
- (void)viewDidLoad
{
[self vinit];
[self.navigationController setNavigationBarHidden:YES animated:NO];
[super viewDidLoad];
[self addRefresh];
[self.swebapi getSurroundImages]; // will call delegate didComposition
}
- (void)viewDidAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:NO];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// cell configuration
}
-(void)addRefresh {
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
self.refresh = refreshControl;
[self.collectionView addSubview:self.refresh];
}
-(void)refresh:(UIRefreshControl*)refresh {
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:#"Refreshing..."];
[self.swebapi getSurroundImages];
}
-(void)didLoadFoo {
[self.swebapi doComposition];
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"toDetailView" sender:indexPath];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"toDetailView"]) {
DetailViewController *dvc = [segue destinationViewController];
NSIndexPath *indexPath = sender;
dvc.idx = [self getItemOfSection:indexPath];
dvc.detailData = [[self.sshare coItem:dvc.idx] mutableCopy];
}
}
- (int)getItemOfSection:(NSIndexPath *)indexPath {
return (int)indexPath.item + ((int)indexPath.section * 4);
}
#end
WebApi.h
#import "AFHTTPRequestOperationManager.h"
#import "Errors.h"
#class WebApi;
#protocol WebApiDelegate <NSObject>
#optional
-(void)didLoadFoo;
#end
#interface WebApi : AFHTTPRequestOperationManager <SingletonDelegate>
#property (assign, nonatomic)id<WebApiDelegate> delegate;
#property (nonatomic, strong) Errors *error;
+(WebApi*)sharedInstance;
-(void)getSurroundStream;
-(void)getSurroundImages;
#end
WebApi.m
#import "WebApi.h"
#define kApiHost #"http://sample.com"
#define kApiPath #"sample"
#implementation WebApi
-(WebApi*)initWithBaseURL:url {
self = [super init];
if (self != nil) {
self.sshare = [SingletonClass sharedInstance];
self.error = [[Errors alloc] init];
}
return self;
}
+(WebApi*)sharedInstance
{
static WebApi *sharedInstance = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
sharedInstance = [[self alloc] initWithBaseURL:[NSURL URLWithString:kApiHost]];
});
return sharedInstance;
}
-(void)getSurroundStream {
NSString *URLString = [NSString stringWithFormat:#"%#/%#/view/%f/%f", kApiHost, kApiPath, self.sshare.coordinate.longitude, self.sshare.coordinate.latitude];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[self setAuthHeader:manager];
[manager GET:URLString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
[self.sshare putViData:responseObject];
[self.delegate performSelector:#selector(didLoadFoo)]; // --> EXC_BAD_ACCESS
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[self.error vError:error message:operation.responseString url:URLString];
}];
}
-(void)getSurroundImages {
[self getSurroundStream];
}
#end
SingletonClass.h
#import <Foundation/Foundation.h>
#class Singleton;
#protocol SingletonDelegate <NSObject>
-(void)didRefreshToken;
#end
#interface SingletonClass : NSObject
#property (assign, nonatomic) id<SingletonDelegate> delegate;
#property (nonatomic, strong) NSMutableArray *viData;
#property (nonatomic, strong) NSMutableArray *coData;
#end
SingletonClasss.m
#import "SingletonClass.h"
#implementation SingletonClass
static SingletonClass *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (SingletonClass *)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
- (id)init
{
self = [super init];
if (self) {
self.coData = [[NSMutableArray alloc] init];
self.viData = [[NSMutableArray alloc] init];
}
return self;
}
// We don't want to allocate a new instance, so return the current one.
+ (id)allocWithZone:(NSZone*)zone {
return [self sharedInstance];
}
// Equally, we don't want to generate multiple copies of the singleton.
- (id)copyWithZone:(NSZone *)zone {
return self;
}
-(NSMutableDictionary *)coItem:(int)position {
NSAssert(self.coData.count > position, #"Position does not exists: coData.count: %lu > position: %d", (unsigned long)self.coData.count, position);
return self.coData[position];
}
#end
DetailViewController.h
#import <UIKit/UIKit.h>
#import "SingletonClass.h"
#import "WebApi.h"
#interface DetailViewController : UITableViewController <WebApiDelegate>
#property (nonatomic) int idx;
#property (nonatomic, strong) SingletonClass *sshare;
#property (nonatomic, strong) WebApi *swebapi;
#property (nonatomic, strong) NSMutableDictionary *detailData;
#end
DetailViewController.m
#import "DetailViewController.h"
#interface DetailViewController ()
#property (nonatomic, strong) NSArray *cellRows;
#end
#implementation DetailViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)vinit {
self.sshare = [SingletonClass sharedInstance];
self.swebapi = [WebApi sharedInstance];
self.swebapi.delegate = self;
NSAssert(self.detailData, #"detailData is not available");
}
- (void)viewDidLoad
{
[self vinit];
[self.navigationController setNavigationBarHidden:NO animated:NO];
[super viewDidLoad];
self.cellRows = #[#"cellLocation:", #"cellIntention:"];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.cellRows.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"detailCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
SEL functionCall = NSSelectorFromString(self.cellRows[indexPath.row]);
[self performSelector:functionCall withObject:cell];
return cell;
}
- (void)cellLocation:(UITableViewCell*)cell {
// configuration of table cell
}
- (void)cellIntention:(UITableViewCell*)cell {
// configuration of table cell
}
#end
You are setting DetailViewController as delegate. Of course you will get EXC_BAD_ACCESS after it's deallocated.
You should use notifications instead delegates for shared instances.
- (void)addObserver:(id)notificationObserver selector:(SEL)notificationSelector name:(NSString *)notificationName object:(id)notificationSender and - (void)removeObserver:(id)notificationObserver are yours friends.
In your protocol, you set didLoadDoo as optional,
#protocol WebApiDelegate <NSObject>
#optional
-(void)didLoadFoo;
#end
so you need to secure the call to that method in your delegate
if ([self.delegate respondsToSelector:#selector(didLoadFoo)]) {
[self.delegate performSelector:#selector(didLoadFoo)];
}
As you are working with a singleton
+(WebApi*)sharedInstance
if your singleton.delegate is change somewhere else in your code (i.e. in your detailVC), it is change everyWhere !
edit :
After some more check, now we know that WebApi.delegate is change in detailVC, and the bug appear when we are back from detailVC because at this step detailVC is becoming nil and of course WebApi.delegate also.
So, the solution is to reset WebApi.delegate when we are back in SurroundViewController, and we can do that in :
SurroundViewController.m
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.swebapi.delegate = self;
}

detailtableview controller to push the image from tableview

hi I'm trying to view the image and description form tableview to detailviewcontroller but not I'm not able get it. I'm fetching the image form server i have stored the image url and using the json and php coding I'm getting the image url using the NSURLConnectionDelegate viewing the images and description in tableview .
i have trying many ways to view those images in the tableview but getting the images.
detailview controller.h file coding
#import <UIKit/UIKit.h>
#import "image.h"
#class image;
#interface viewdetailpoliticalViewController : UIViewController<NSURLConnectionDelegate>
{
NSURLConnection *connection;
}
#property (strong,nonatomic) NSString *value;
#property (strong,nonatomic) UIImage *imm;
#property (strong, nonatomic) IBOutlet UIImageView *imageview;
#property (strong, nonatomic) IBOutlet UILabel *dcp
#property (strong, nonatomic) NSMutableData *responseData;
-(void)setDataSource:(image *)inImageOb;
#end
this is my detailview controller.m file coding
#import "viewdetailpoliticalViewController.h"
#import "image.h"
#interface viewdetailpoliticalViewController ()
#end
#implementation viewdetailpoliticalViewController
#synthesize imageview,dcp;
#synthesize value,imm;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageview.image = self.imm;
self.dcp.text = self.value;
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)setDataSource:(image *)inImageOb
{
self.value = inImageOb.desp;
NSURL *url = [NSURL URLWithString:inImageOb.img];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
{
[self.responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
{
UIImage *image = [UIImage imageWithData:self.responseData];
self.imm = image;
}
#end
this is my tableview controller m file coding:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"Detailsegue" sender:indexPath];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Detailsegue"]) {
viewdetailpoliticalViewController *detailvc = (viewdetailpoliticalViewController *)segue.destinationViewController;
NSIndexPath *indexPath =[self.mytableview indexPathForSelectedRow];
[detailvc setDataSource:[imgevery objectAtIndex:indexPath.row]];
}
}
this is code i have used to fetch the datas using json
-(void) retrieveData
{
NSURL * url = [NSURL URLWithString:getDataURL];
NSData * data = [NSData dataWithContentsOfURL:url];
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
imgevery =[[NSMutableArray alloc]init];
for (int i=0; i<json.count; i++) {
NSString * dd = [[json objectAtIndex:i]objectForKey:#"imgp"];
NSString * plae =[[json objectAtIndex:i]objectForKey:#"disp"];
image *myimg =[[image alloc]initWithimg:dd anddesp:plae];
[imgevery addObject:myimg];
}
[self.mytableview reloadData];
}
this is the code i have used for the tableview cell
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return imgevery.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier =#"Cell";
imgpoliticalCell *cell =(imgpoliticalCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell== nil) {
cell = [[imgpoliticalCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
[cell setDataSource:[imgevery objectAtIndex:indexPath.row]];
// cell.thumbImageView.image = _img;
return cell;
}
Found the problem the problem is u passing data through Setimage Source
you set image in viewDidload itself after -(void)setDataSource:(image *)inImageOb only viewDidload () will run but you assigned image to imageview in viewDidLoad() itself
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageview.image = self.imm;
self.dcp.text = self.value;
// Do any additional setup after loading the view.
}
(void)connectionDidFinishLoading will run after ViewDidLoad()
SO you ve to set Image in - (void)connectionDidFinishLoading:(NSURLConnection *)connection; only which will run at last when connection didFinish so do like this
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
{
imm = [UIImage imageWithData:self.responseData];
self.dcp.text = value;
self.imageview.image = imm;
}
Hope Now works...

Resources