I am trying to implement a car2go style app where you click on an annotation view and then can reserve the car. The problem is when I try to segue I want to pass the car object over, I check if the object performs the selector set vehicle but the if statement fails although I am pretty sure it is implemented. Can someone tell me why? This is for a school project.
#import "MapViewController.h"
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "Vehicles+Company.h"
#import "Vehicles+MKAnnotation.h"
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"reserveCar"]) {
if ([sender isKindOfClass:[MKAnnotationView class]]) {
MKAnnotationView *aView = sender;
if ([aView.annotation isKindOfClass:[Vehicles class]]) {
Vehicles *vehicle = aView.annotation;
if ([segue.destinationViewController respondsToSelector:#selector(setVehicle:)]) {
[segue.destinationViewController performSelector:#selector(setVehicle:) withObject:vehicle];
}
}
}
}
}
This is the viewcontroller it is segueing to.
.h file
#import <UIKit/UIKit.h>
#import "Vehicles+MKAnnotation.h"
#import "Vehicles.h"
#import "Vehicles+Company.h"
#interface CompanyVehicleViewController : UIViewController
#property (nonatomic,strong) Vehicles *vehicle;
#end
.m file
#import "CompanyVehicleViewController.h"
#interface CompanyVehicleViewController ()
#end
#implementation CompanyVehicleViewController
-(void) setVehicle:(Vehicles *)vehicle{
_vehicle = vehicle;
self.title = vehicle.name;
NSLog(#"Vehicle is %#", vehicle);
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
#end
Most likely segue.destinationViewController isn't an instance of CompanyVehicleViewController.
Verify in your storyboard that the view controller's type is set to the proper class.
Related
im new to iOS and its developing .there i have used iOS delegates to pass values in between view controllers
1. Essentialinfocontroller - its got TableView
2. detailcontroller -
i want to pass values of Essentialinfocontroller to detailcontroller
to do that i used delegates but nothing print on console please help me.
Essentialinfocontroller.h
#import <UIKit/UIKit.h>
#protocol sendTestData <NSObject>
-(void)sendDataToA:(NSArray *)array;
#end
#interface Essentialinfocontroller : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *info;
#property (nonatomic,strong) NSDictionary * courses;
#property (nonatomic, strong)NSArray *coursekeys;
#property(nonatomic,strong) NSString* customeLink;
#property (nonatomic,retain)NSArray * array;
#property(nonatomic,assign)id delegate;
#end
Essentialinfocontroller.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0){
[self giveValuestoNSmutableArray];
[delegate sendDataToA:array];
}
}
-(void)giveValuestoNSmutableArray
{
array = [NSArray arrayWithObjects:#"Jill Valentine", #"Peter Griffin", #"Meg Griffin", #"Jack Lolwut",
#"Mike Roflcoptor", #"Cindy Woods", #"Jessica Windmill", #"Alexander The Great",
#"Sarah Peterson", #"Scott Scottland", #"Geoff Fanta", #"Amanda Pope", #"Michael Meyers",
#"Richard Biggus", #"Montey Python", #"Mike Wut", #"Fake Person", #"Chair",
nil];
}
detailcontroller.h
#import <UIKit/UIKit.h>
#import "Essentialinfocontroller.h"
#interface detailcontroller : UIViewController <sendTestData>
#end
detailcontroller.m
#import "detailcontroller.h"
#interface detailcontroller ()
#end
#implementation detailcontroller
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
Essentialinfocontroller * acontollerobject=[[Essentialinfocontroller alloc] initWithNibName:#"Essentialinfocontroller" bundle:nil];
acontollerobject.delegate=self; // protocol listener
[self.navigationController pushViewController:acontollerobject animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)sendDataToA:(NSArray *)array
{
for (NSString *string in array) {
NSLog(#"%#", string);
}
}
#end
You've got the relationship between controllers and delegates a little backwards. A delegate is used to pass information back. Your tableViewController is the detailController's delegate, and detailController shouldn't be allocating an EssentialInfoController inside it. You're basically creating a whole new EssentialInfoController that's different from the first one.
The easiest way to pass data is just to set it when the detailController is allocated. Also, since you're using storyboards, you have to use (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender to allocate the detailController.
Here's what I would do:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0){
[self performSegueWithIdentifier:#"OpenDetailsController"];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
DetailController *controller = (DetailController *)[segue destinationViewController];
NSArray *array = <your array here>;
[controller setArray:array];
}
In your storyboard, set the Storyboard Segue Identifier for that segue to "OpenDetailsController".
A delegate function is defined through a protocol, and you would have the DetailController call its delegate like this:
[self.delegate doSomething];
And in the EssentialInfoViewController you have to define the delegate function
-(void)doSomething {
}
I'm writing a method that takes a string from a textfield, and sends it over to a cloudcode function on Parse's end. Xcode is giving me the error Use of undeclared identifier 'PFCloud', even though I've imported the parse header in SearchViewController.h. What could be causing this?
SearchViewController.m:
#import "SearchViewController.h"
#interface SearchViewController ()
#property (weak, nonatomic) IBOutlet UITextField *itemSearch;
#property (weak, nonatomic) IBOutlet UIButton *nextButton;
#end
#implementation SearchViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#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
{
if (sender != self.nextButton) return;
if (self.itemSearch.text.length > 0) {
[PFCloud callFunctionInBackground:#"averageStars"
withParameters:#{#"item": self.itemSearch.text}
block:^(NSNumber *ratings, NSError *error) {
if (!error) {
// ratings is 4.5
}
}];
}
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
#end
SearchViewController.h:
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#interface SearchViewController : UIViewController
#end
I'm trying to separate the UITextViewDelegate methods from the main class of my project, I created a class to manage the delegate methods, but I can not change the values of the IBOulets from the main class.
I made a test project with a ViewController and a TextFieldController, in the Storyboard I add a text field and a label. What I want to do is change the text of the label when I start to write in the text field. Here is the code:
ViewController.h:
#import <UIKit/UIKit.h>
#import "TextFieldController.h"
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITextField *textField;
#property (strong, nonatomic) IBOutlet UILabel *charactersLabel;
#end
ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) TextFieldController *textFieldController;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_textFieldController = [[TextFieldController alloc] init];
_textField.delegate = _textFieldController;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
TextFieldController.h:
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface TextFieldController : UIViewController <UITextFieldDelegate>
#end
Text Field Controller.m:
#import "TextFieldController.h"
#interface TextFieldController ()
#property ViewController *viewController;
#end
#implementation TextFieldController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL) textFieldShouldBeginEditing:(UITextField *)textField {
NSLog(#"hello");
_viewController.charactersLabel.text = #"hello";
return YES;
}
#end
When I start writing in the text field the message "Hello" is printed in the log, but the text of the label does not change. I want to know how to change the label text value from the other class.
First change the TextFieldController.h like this:
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface TextFieldController : NSObject <UITextFieldDelegate>
{
}
#property (nonatomic, assign) ViewController *viewController;
#end
Then change your TextFieldController.m file like this:
#import "TextFieldController.h"
#interface TextFieldController ()
#end
#implementation TextFieldController
- (BOOL) textFieldShouldBeginEditing:(UITextField *)textField {
NSLog(#"hello");
self.viewController.charactersLabel.text = #"hello";
return YES;
}
#end
In the ViewController.m do like that:
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) TextFieldController *textFieldController;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_textFieldController = [[TextFieldController alloc] init];
_textFieldController.viewController = self;
_textField.delegate = _textFieldController;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
This will work but I personally dont like that way you took.
Good luck :)
It's failing because _viewController is nil. You need to assign the viewController property in your delegate in order to support the two way communication.
Also, I'd strongly recommend you make your delegate object a subclass of NSObject, and not UIViewController. It does nothing with controlling views. You can just manually instantiate it in your ViewController objects viewDidLoad.
In TextViewController I don't see where the viewController property (_viewController ivar) is being set so it is probably nil. You should set it when you create the TextViewController instance.
When you are navigating to other controllers using storyboad's segue then you need to implement prepareForSegue method to initialised its properties as follows
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"segue for textFieldController"])
{
TextFieldController *_textFieldController = [segue destinationViewController];
_textField.delegate = _textFieldController;
}
}
But I was wondering, why are you setting textFieldDelegate here, why can't you set in TextFieldController's viewDidLoad method as then you didn't you to implement above prepareForSegue method call?
Besides you are keeping strong reference of each other and you are creating strong retain cycle.
One more thing, following code
_textField.delegate = _textFieldController;
will not work, until textFieldController is loaded and its viewDidLoad method is being called as you are only initialising it but its outlets will not be connected until view is loaded into navigation stack.
I have a tableview using ODRefreshControll. And i have a uislider which is in another view controller (let say myViewController) and this slider is changing a variable (let say myVariable) of tableview. The main issue is if i change myVariable from myViewController with slider and refresh the tableview, myVariable turns its initial value. I will provide my code but it is a little bit mess code, so please ask anything you do not understand from code.
Here is my code:
At myTableView.h:
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "ODRefreshControl.h"
#interface myTableView : UITableViewController
-(void)gettingVariableFromMyViewController;
#end
At myTableView.m
#import "MekanListesi.h"
#import "AppDelegate.h"
#import "Ayarlar.h"
#interface myTableView ()
#property(strong)NSNumber *myVariable;
#end
#implementation myTableView
#synthesize myVariable;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
-(void)gettingVariableFromMyViewController{
NSString *unsettedVariable = [(AppDelegate *)[[UIApplication sharedApplication] delegate] variableUniversal];
if (!unsettedVariable) {
unsettedVariable= #"10000000000000000";
}
NSNumberFormatter * NSNF= [[NSNumberFormatter alloc] init];
[NSNF setNumberStyle:NSNumberFormatterDecimalStyle];
self.myVariable=[DegmesinEllerimiz numberFromString:AlinanYariCap];
}
- (void)dropViewDidBeginRefreshing:(ODRefreshControl *)refreshControl
{
double delayInSeconds = 1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[refreshControl endRefreshing];
});
}
At myViewController.h
#import <UIKit/UIKit.h>
#interface myViewController : UIViewController
#property (weak, nonatomic) IBOutlet UISlider *mySlider;
- (IBAction)actionMySlider:(id)sender;
#property (weak, nonatomic) IBOutlet UILabel *myVariabelLabel;
#end
At myViewController.m
#import "myViewController.h"
#import "AppDelegate.h"
#import "myTableView.h"
#interface myViewController()
#end
#implementation myViewController
#synthesize myVariableLabel;
#synthesize mySlider;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)actionMySlider:(id)sender{
myVariableLabel.text = [NSString stringWithFormat:#"%1.1f",mySlider.value];
[(AppDelegate *)[[UIApplication sharedApplication] delegate] setuniversalVariable:[NSString stringWithFormat:#"%f",mySlider.value]];
myTableView *MTV=[[myTableView alloc]init];
[MTV gettingVariableFromMyViewController];
[MTV.tableView reloadData];
}
(At appdelegate universalVariable setted as
#property(nonatomic,retain)NSString *universalVariable;
#synthesize universalVariable;
)
note: I am coping and pasting that code from xcode and make some changes with names of methods, classes and variables due to the fact that my native language is not English, so there can be some mistakes about names of those, Please warn me if you see one of those errors.
Thank you.
The problem is not the pull to refresh, the problem is in your code that somewhere you are setting the wrong value for your variable. Also where are you setting the new value for your variable, because in gettingVariableFromMyViewController you are checking the value store in your app delegate so if you don't set anywhere the new value in the app delegate, the gettingVariableFromMyViewController will return/set the same value #"10000000000000000
I have two view controllers: BSViewController and BSotherViewController. BSViewController has a button on it that is segues to BSotherViewController. That part works fine and I can see the one VC and then the "other" VC when I run on the simulator. But I have an NSLog(#"other"); in BSotherViewController's -viewDidLoad which is not showing in the console. A similar NSLog(#"other"); in BSViewController's -viewDidLoad which is showing in the console. I suspect the problem is the lack of an IBAction but I cannot figure where it should go and how it should be linked in the storyboard.
BSViewController.h
#import <UIKit/UIKit.h>
#interface BSViewController : UIViewController
#property (nonatomic) NSInteger number;
#end
BSViewController.m
#import "BSViewController.h"
#interface BSViewController ()
#end
#implementation BSViewController
#synthesize number;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.number = 25;
NSLog(#"number: %d", self.number);
}
#end
BSotherViewController.h
#import <UIKit/UIKit.h>
#interface BSotherViewController : UIViewController
#property (nonatomic) NSInteger anumber;
#end
BSotherViewController.m
#import "BSotherViewController.h"
#include "BSViewController.h"
#interface BSotherViewController ()
#end
#implementation BSotherViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
NSLog(#"other number:");
[super viewDidLoad];
// Do any additional setup after loading the view.
BSViewController *view = [[BSViewController alloc] init];
self.anumber = view.number;
NSLog(#"other number: %d", self.anumber);
}
In the storyboard is the second view controller set up as a BSotherViewController? You can verify by hovering over the view controller icon in the storyboard.
If it's not, then click it and go to the identity controller and type it in.