Passing complex double value from ViewController to another ViewController - ios

I need to pass complex double value from ViewController to another ViewController. XCODE prompted me with this error "Assigning to NSString from incompatible type 'complex number'"
ViewController.m
complex double A=0+0*I;
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"Calculate"]){
[self ComputeABCD];
ResultViewController *controller = (ResultViewController *)segue.destinationViewController;
controller.textContent = cascadedA;
}
}
ResultViewController.m
#implementation ResultViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.result.text = self.textContent;
}
ResultViewController.h
#interface ResultViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *result;
#property (nonatomic, assign) complex double textContent;
#property (nonatomic, assign) complex double textValue;
#end

Related

What are the methods to pass forward data from one View Controller to another using button action?

I'm just a beginner in iOS Devp and stuck with this problem since last 2days. What I am trying to do is I've two view controllers, the first View Controller consists of 2 buttons and I want to load a specific type of data in next View controller on respective button action.
What I did is as follows :
I've two ViewControllers connected using segue with id "showDetailSegue",
1. ViewController
2. SecondVC
I want to update label on SecondVC when the button on ViewController is tapped.
//ViewController.h
#import <UIKit/UIKit.h>
#import "SecondVC.h"
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *textField;
#end
//ViewController.m
#import "ViewController.h"
#import "SecondVC.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
NSString *str = #"my string data..";
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"showDetailSegue"]){
SecondVC *controller = segue.destinationViewController;
controller.getString = str;
controller.testLabel.text = str;
}
}
#end
//SecondVC.h
#import <UIKit/UIKit.h>
#interface SecondVC : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *testLabel;
#property (nonatomic, strong) NSString *getString;
#end
//SecondVC.m
Please help me with a straightforward and clear explanation.
Thanks in advance.!
There are many ways to pass data to desired ViewController.
1. Using segue
Let suppose you have to pass a string to another VC.
#import "ViewController.h"
#import "SecondVC.h"
#interface ViewController ()
// all instance global variable should be declare here
NSString str;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
str = #"my string data..";
}
// segue delegate method
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"segueIdentifireName"]) {
SecondVC *destViewController = segue.destinationViewController;
destViewController.getString = str;
}
}
#end
Now you must have to create NSString object inside destinationVc .h file like below.
#interface SecondVC : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *testLabel;
#property (nonatomic, strong) NSString *getString;
#end
Inside .m file get string data like:
#interface ViewController ()
#end
#implementation SecondVC
- (void)viewDidLoad {
[super viewDidLoad];
self.testLabel.text = getString; // we passed `str` data inside `getString` object so it can be refelect here using `getString` variable.
NSLog(#"string data %#", getString);
}
2. Using storyboard id:
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
YourViewControllerClassName *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"viewContIdentifire"];
vc.getString = str;
[self.navigationController pushViewController:vc animated:YES];
Inside .h file:
#property (nonatomic, strong) NSString *getString;
Inside .m file get string data like:
NSLog(#"string data %#", getString);
In Swift3
let controller = UIStoryboard().getControllerInstance(storyBoardName: "MainStoryboard", identifire: "viewContIdentifire")
controller.getString = str;
self.navigationController?.pushViewController(controller, animated: true)
To get data back:
Create protocol where you need to send data back.
// dec var on top
var delegate: YourDelegate!
protocol YourDelegate {
func delegateFunction(value: String)
}
Call delegate func on tap action:
delegate.delegateFunction(value: "My sample string")
Receiving controller
Confirm the delegate to self when navigate
Implement the YourDelegate on top.
func delegateFunction(value: String){
print("Got: ", value)
}
3. Using NSUserDefaluts (Not recommended).
4. Using local DB.

Objective-C issue with Segue

I have this Segue here:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
//NSDate *object = self.objects[indexPath.row];
NSString *strPOIndex = [self.tableData[indexPath.row] valueForKey:#"POIndex"];
LHPurchaseOrderDetail *controller = (LHPurchaseOrderDetail *)[[segue destinationViewController] topViewController];
[controller setDetailItem:strPOIndex];
controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;
}
}
and what I am trying to do with it is pass strPOIndex to setDetailItem in my detail controller from my master controller.. but when I run this, I get an error:
-[LHPurchaseOrderMaster setDetailItem:]: unrecognized selector sent to instance 0x156cce80
I dont understand why this is happening, is it an issue with my storyboard? or my master controller or detail controller? Here is my Detail Controller:
.h:
#import <UIKit/UIKit.h>
#interface LHPurchaseOrderDetail : UIViewController
#property (strong, nonatomic) IBOutlet UINavigationBar *NavBar;
#property (strong, nonatomic) id detailItem;
#property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#end
.m:
#import "LHPurchaseOrderDetail.h"
#interface LHPurchaseOrderDetail ()
#end
#implementation LHPurchaseOrderDetail
- (void)setDetailItem:(id)newDetailItem {
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}
- (void)configureView {
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[self configureView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end
Master Controller:
.h
#import <UIKit/UIKit.h>
#import "ShinobiDataSource.h"
#import "PopupGenerator.h"
#class LHPurchaseOrderDetail;
#interface LHPurchaseOrderMaster : UITableViewController<UIPopoverControllerDelegate, UIPickerViewDelegate>
#property (strong, nonatomic) IBOutlet UIButton *communityBtn;
#property (strong, nonatomic) IBOutlet UIButton *lotBtn;
#property (strong, nonatomic) IBOutlet UIButton *goBtn;
- (IBAction)communityBtnPressed:(id)sender;
- (IBAction)lotBtnPressed:(id)sender;
- (IBAction)goBtnPressed:(id)sender;
#property(nonatomic, retain) NSArray * tableData;
#property (strong, nonatomic) LHPurchaseOrderDetail *purchaseOrderController;
#end
Your error is this:
-[LHPurchaseOrderMaster setDetailItem:]: unrecognized selector sent to instance 0x156cce80
so it seems that somewhere in your LHPurchaseOrderMaster class you're trying to access and set the detailItem property as if it would be a part of LHPurchaseOrderMaster but because it doesn't exist there, you get an unrecognized selector error.
Edit
You should check for three things:
In Interface Builder check that the segue from LHPurchaseOrderMaster ViewController is to an UINavigationController that embeds the LHPurchaseOrderDetail ViewController as the first view controller in its stack.
Check the Class name returned by [segue destinationViewController]topViewController] like this:
id obj = [segue destinationViewController]topViewController];
NSLog(#"%#", NSStringFromClass([obj class]));
The class name should be LHPurchaseOrderDetail. If it's not, then you have a problem in your Storyboard where more than certainly you've connected the segue wrong.
Check your LHPurchaseOrderMaster class for any code that tries to access the "detailItem" property as if it would be part of this class.
It seems that the property you are trying to access is not accessible (wrong retrieved object).
Have you tried to use instead of
LHPurchaseOrderDetail *controller = (LHPurchaseOrderDetail *)[[segue destinationViewController] topViewController];
Something like
LHPurchaseOrderDetail *controller = (LHPurchaseOrderDetail *)[[segue destinationViewController] viewControllers][0];
I had sometimes the same your issue.
Set your detailItem not to NSString. Not to id. The problem is here,
self.detailDescriptionLabel.text = [self.detailItem description];
In configureView method change the code as follow,
- (void)configureView {
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = self.detailItem;
}
}
Don't forget to change this as well,
- (void)setDetailItem:(NSString *)newDetailItem {
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
}

How to access property in different view controller?

I have two storyboards and each one has its own respective view controller but I need to change the appearance of the second storyboard based on the button pressed in the first view controller.
In the first view controller I have:
// First view controller .h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface FirstViewController : UIViewController
#property (strong, nonatomic) IBOutlet UIButton *LevelOneButton; // tag 0
#property (strong, nonatomic) IBOutlet UIButton *LevelTwoButton; // tag 1
-(IBAction)selectLevel:(UIButton *)sender; // both buttons connected to this method
#property (assign, nonatomic) int levelSelect;
#end
then in the first .m file:
//FirstViewController.m
-(IBAction)selectLevel:(UIButton *)sender {
if (sender.tag == 0) {
_levelSelect = 0;
}
if (sender.tag == 1) {
_levelSelect = 1;
}
}
This code works fine but the problem occurs in the secondViewController that I have. When I try and access the levelSelect property in the SecondViewController I get the errors "Property 'levelSelect' not found on object of type 'FirstViewController'" or "Unexpected identifier levelSelect" or something among those lines. I've tried every single thing I could think of and every question I found on StackOverflow relating to this but none have fixed the problem. Anyone know what I'm doing wrong?
You should be setting the property on the second view controller as you're pushing or segueing.
So in your first view controller it should look something like this:
#import "ViewController.h"
#import "SecondViewController.h"
#interface ViewController ()
#property (strong, nonatomic) IBOutlet UIButton *levelOne;
#property (strong, nonatomic) IBOutlet UIButton *levelTwo;
#property (assign, nonatomic) int selectedLevel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.levelOne.tag = 1;
self.levelTwo.tag = 2;
}
- (IBAction)selectLevel:(UIButton *)sender
{
if (sender.tag == 1) {
self.selectedLevel = 1;
} else {
self.selectedLevel = 2;
}
[self performSegueWithIdentifier:#"pushToSecond" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SecondViewController *dest = segue.destinationViewController;
dest.levelSelect = self.selectedLevel;
}
#end
Now, when viewDidLoad gets called on the SecondViewController that property will be set and you can use it. Like so:
#import "SecondViewController.h"
#interface SecondViewController ()
#property (strong, nonatomic) IBOutlet UILabel *levelLabel;
#end
#implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.levelLabel.text = [#(self.levelSelect) stringValue];
}
#end
Quick Edit, if you're not using segues you can do the same thing by pushing manually. Would look something like:
- (IBAction)selectLevel:(UIButton *)sender
{
if (sender.tag == 1) {
self.selectedLevel = 1;
} else {
self.selectedLevel = 2;
}
SecondViewController *secondVC = [[UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:#"second"];
secondVC.levelSelect = self.selectedLevel;
[self.navigationController pushViewController:secondVC animated:YES];
}

Why delegate protocol method is not recognized in UINavigationController

I looked at lots of threads about delegation but couldn't find why this isn't working
I have UINavigationController in storyboard in Xcode 5 and here is how the delegate is assigned:
in MasterViewController I have:
//
// MasterViewController.h
//
#protocol MyViewDelegate
#required
- (void) getBackContacts:(NSArray *)c andEmails:(NSArray *)e;
#end
#interface ListContactsViewController : UITableViewController <MyViewDelegate> {
}
#property (strong, nonatomic) NSString* myString;
#property (strong, nonatomic) ABContact* currentML;
#end
//
// MasterViewController.m
//
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
DetailtViewController *vc = [segue destinationViewController];
vc.delegate = self;
vc.currentML = _currentML;
vc.contacts = _contacts;
vc.emails = _emails;
}
- (void) getBackContacts:(NSArray *)c andEmails:(NSArray *)e
{
_contacts = [NSMutableArray arrayWithArray:c];
_emails = [NSMutableArray arrayWithArray:e];
}
for DetailViewController I have:
//
// DetailViewController.h
//
#protocol MyViewDelegate;
#interface SelectContactViewController : UITableViewController {
id< MyViewDelegate > delegate;
}
-(IBAction) save;
#property (nonatomic, strong) id< MyViewDelegate > delegate;
#property (strong, nonatomic) ABContact* currentML;
#property (strong, nonatomic) NSMutableArray* contacts;
#property (strong, nonatomic) NSMutableArray* emails;
//
// DetailViewController.m
//
- (IBAction) save
{
// *** this line compiles with error
[delegate getBackContacts:_contacts andEmails:_emails];
}
When I compile compiler says:
No known instance method for selector 'getBackContacts:andEmails:'

'NSInvalidArgumentException', reason: '-[UINavigationController setMed:]: unrecognized selector sent to instance 0x746dda0'

I am making an app that will help people with certain health conditions manage their medication. I have created a modal to add medication which works and saves the new medication using core data.
I am now trying to allow people to edit their medication after it has been saved. To do this I am trying to send a managed object of the medication to a "fibromappMedsEditViewController" and assign the information in the viewDidLoad method of the class.
I keep getting this error:
'NSInvalidArgumentException', reason: '-[UINavigationController setMed:]: unrecognized selector sent to instance 0x746dda0'
Could anybody tell me what I am doing wrong?
relevant methods in fibromappMedsListViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{ //selMed declared at top of file as NSManagedObject *selMed;
selMed = [self.meds objectAtIndex:indexPath.row];
NSLog(#"SELECTED MED: %#",[selMed valueForKey:#"name"] );
UIStoryboardSegue *segueString = [NSString stringWithFormat:#"%#",#"editMeds"];
NSLog(#"%#",segueString);
[self performSegueWithIdentifier:#"editMeds" sender:indexPath];
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSLog(#"%#",segue.destinationViewController);
NSLog(#"%#",[selMed valueForKey:#"name"] );
fibroMappMedsEditViewController *dest = segue.destinationViewController;
dest.med = selMed;
}
The fibroMappMedsEditViewController.h
#import <UIKit/UIKit.h>
#interface fibroMappMedsEditViewController : UITableViewController
- (IBAction)saveChanges:(id)sender;
- (IBAction)deleteBtnPressed:(id)sender;
- (IBAction)dosageChanged:(id)sender;
- (IBAction)maxDosageChanged:(id)sender;
- (IBAction)cancel:(id)sender;
- (IBAction)typeChanged:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *tbName;
#property (weak, nonatomic) IBOutlet UITextField *tbDose;
#property (weak, nonatomic) IBOutlet UITextField *tbMaxDose;
#property (weak, nonatomic) IBOutlet UITextField *tbType;
#property (weak, nonatomic) IBOutlet UIStepper *stepperDose;
#property (weak, nonatomic) IBOutlet UIStepper *stepperMaxDose;
#property (weak, nonatomic) IBOutlet UISegmentedControl *changeMeasure;
#property (strong, nonatomic) NSManagedObject *med;
#end
The fibroMappMedsEditViewController.m - just the parts I altered that affect the way the controller loads
#import "fibroMappMedsEditViewController.h"
#import "fibroMappAppDelegate.h"
#import <CoreData/CoreData.h>
#interface fibroMappMedsEditViewController ()
#end
#implementation fibroMappMedsEditViewController
#synthesize tbName;
#synthesize tbDose;
#synthesize tbMaxDose;
#synthesize tbType;
#synthesize med;
double dose;
double maxDose;
- (void)viewDidLoad
{
[super viewDidLoad];
tbName.text = [med valueForKey:#"name"];//name is a string in the model
tbDose.text = [med valueForKey:#"dose"];//dose is a double in the model
tbMaxDose.text = [med valueForKey:#"maxDose"];//maxDose is a double in the model
tbType.text = [med valueForKey:#"type"];//type is a string in the model
}
If you need to see anything else please just ask.
Also, I am using storyboards for this app.
It appears from that log, that your fibroMappMedsEditViewController (which should start with a capital letter BTW) is embedded in a navigation controller. You need to get to that navigation controller's root view controller.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
UINavigationController *nav = segue.destinationViewController;
fibroMappMedsEditViewController *dest = (fibroMappMedsEditViewController *)nav.topViewController;
dest.med = selMed;
}

Resources