Ok so I am attempting to pass an int to another interface, edit the int and give it back to the original interface. I am trying to use a delegate to achieve this and I believe I have it setup correctly and it appears the method is not being called when its supposed to.
//
// InterfaceController.h
// DelegateTest WatchKit Extension
//
// Created by Rohan Hodge on 20/10/2015.
// Copyright © 2015 Hodge Development. All rights reserved.
//
#import <WatchKit/WatchKit.h>
#import <Foundation/Foundation.h>
#import "SecondController.h"
#interface InterfaceController : WKInterfaceController <DelegateTest>
{
NSTimer *Update;
}
#property (strong, nonatomic) IBOutlet WKInterfaceLabel *FirstControllerLabel;
#property (nonatomic,assign) int FirstInteger;
#property (nonatomic,assign) int RecievedInteger;
#property (nonatomic,assign) NSString *PassString;
#end
// InterfaceController.m
// DelegateTest WatchKit Extension
//
// Created by Rohan Hodge on 20/10/2015.
// Copyright © 2015 Hodge Development. All rights reserved.
//
#import "InterfaceController.h"
#interface InterfaceController()
#end
#implementation InterfaceController
#synthesize FirstInteger;
#synthesize RecievedInteger;
#synthesize PassString;
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
// Configure interface objects here.
}
-(void)UpdateVoid
{
self.FirstControllerLabel.text = [NSString stringWithFormat:#"%i", FirstInteger];
}
- (void)willActivate {
SecondController *interfaceController;
interfaceController.delegate = self;
Update = [NSTimer timerWithTimeInterval:1.0 target:self selector:#selector(UpdateVoid) userInfo:nil repeats:YES];
// This method is called when watch view controller is about to be visible to user
[super willActivate];
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
}
-(void)DelegateMethod:(int)ReturningInt
{
[self popController];
FirstInteger = ReturningInt;
self.FirstControllerLabel.text = [NSString stringWithFormat:#"%i", FirstInteger];
}
- (IBAction)UpButton {
FirstInteger++;
self.FirstControllerLabel.text = [NSString stringWithFormat:#"%i", FirstInteger];
}
- (IBAction)DownButton {
FirstInteger--;
self.FirstControllerLabel.text = [NSString stringWithFormat:#"%i", FirstInteger];
}
- (IBAction)PassDataButton {
PassString = [NSString stringWithFormat:#"%i", FirstInteger];
[self pushControllerWithName:#"SecondController" context:PassString];
}
#end
//
// SecondController.h
// DelegateTest
//
// Created by Rohan Hodge on 20/10/2015.
// Copyright © 2015 Hodge Development. All rights reserved.
//
#import <WatchKit/WatchKit.h>
#import <Foundation/Foundation.h>
//This declaration of delegate.
#protocol DelegateTest <NSObject>
-(void) DelegateMethod:(int)ReturningInt;
#end
#interface SecondController : WKInterfaceController
{
id delegate;
}
#property (nonatomic, assign) id <DelegateTest> delegate;
#property (strong, nonatomic) IBOutlet WKInterfaceLabel *SecondLabel;
#property (nonatomic,assign) NSString *RecievedString;
#property (nonatomic, assign) int FirstReceivedInteger;
#end
//
// SecondController.m
// DelegateTest
//
// Created by Rohan Hodge on 20/10/2015.
// Copyright © 2015 Hodge Development. All rights reserved.
//
#import "SecondController.h"
#import "InterfaceController.h"
#interface SecondController ()
#end
#implementation SecondController
#synthesize SecondLabel;
#synthesize FirstReceivedInteger;
#synthesize RecievedString;
#synthesize delegate = _delegate;
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
//This is where I receive the int inside of a string and split it from the string so I can change it
RecievedString = context;
FirstReceivedInteger = [RecievedString intValue];
// Configure interface objects here.
}
- (void)willActivate {
self.SecondLabel.text = [NSString stringWithFormat:#"%i",FirstReceivedInteger];
// This method is called when watch view controller is about to be visible to user
[super willActivate];
}
- (IBAction)UpButton {
FirstReceivedInteger++;
self.SecondLabel.text = [NSString stringWithFormat:#"%i",FirstReceivedInteger];
}
- (IBAction)DownButton {
FirstReceivedInteger--;
self.SecondLabel.text = [NSString stringWithFormat:#"%i",FirstReceivedInteger];
}
//This is a button that is ment to pass back the int.
- (IBAction)ReturnToOriginalInterface:(id)sender{
[self.delegate DelegateMethod:FirstReceivedInteger];
}
- (void)didDeactivate {
// This method is called when watch view controller is no longer visible
[super didDeactivate];
}
#end
I'm new to Stack Overflow, Sorry about the messy code formatting.
P.S I use the Arrow in the top left of the interface to return to the original Interface. Also am using Objective-C
Thanks in advance.
You need to set a property or method to change in your controller (that your first controller will change) and you get back the result with a delegate pattern.
You're attempting to do this in a Watch app, yes? I don't know that delegates don't work, but when I did this for my Watch app, I used the context parameter of WKInterfaceController::presentControllerWithName:context:.
context is a NSDictionary of the values you want to pass around. One of those values could be a pointer to the presenting controller.
So, trying to decipher what you're attempting in your app, I believe the proper thing to do is:
In the ORIGINAL WKInterfaceController:
- (IBAction)buttonThatOpensOtherIC
{
NSDictionary *context = #{
#"firstController" : self,
};
[self pushControllerWithName:#"Other IC"
context:context];
}
}
In the OTHER WKInterfaceController:
- (void)awakeWithContext:(id)context {
[super awakeWithContext:context];
if (context)
{
self.originalInterfaceController = context[#"firstController"];
}
}
//This is the button that calls the delegate method.
- (IBAction)ReturnToOriginalInterface:(id)sender
{
// [self.delegate DelegateMethod:FirstReceivedInteger];
if (self.originalInterfaceController) {
self.originalInterfaceController.firstInteger = self.returningInt;
}
[self popController];
}
*Note the use of awakeWithContext: in the OTHER interface controller.
DISCLAIMER #1: I haven't executed this code, so there may be a typo in it. It is an adaptation for you of working code I do use.
DISCLAIMER #2: I haven't updated my app for WatchOS 2. I doubt this part of things changed, but it is possible.
Related
I have a method which need receive a Byte[] :
In the .h file:
- (void)setPC1_APPKEY:(Byte[] )pC1_APPKEY;
In the .m file:
I want to own a Byte[] property to save it.
But when I declare the property like this:
#property (nonatomic, assign) Byte PC1_APPKEY[];
It shows error:property cannot have array or function type'Byte[]'
And so I set it to attribute like this:
{
Byte PC1_APPKEY[];
}
It shows error:Field has Incomplete type ‘Byte[]’
How can I get the Byte[] ? thanks.
you can use Pointer like this
#property (nonatomic, assign) Byte *PC1_APPKEY;
all files
.h
//
// ocViewController.h
// testTableViewHeader
//
// Created by 刷脸卡 on 10/11/16.
// Copyright © 2016 曾祥林. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface TestViewController : UIViewController
- (void)setPC1_APPKEY:(Byte[] )pC1_APPKEY;
#end
.m
//
// ocViewController.m
// testTableViewHeader
//
// Created by 刷脸卡 on 10/11/16.
// Copyright © 2016 曾祥林. All rights reserved.
//
#import "TestViewController.h"
#interface TestViewController ()
#property (nonatomic, assign) Byte *PC1_APPKEY;
#end
#implementation TestViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *testString = #"1234567890";
NSData *testData = [testString dataUsingEncoding: NSUTF8StringEncoding];
self.PC1_APPKEY = (Byte *)[testData bytes];
for(int i=0;i<[testData length];i++){
printf("testByte = %d\n",self.PC1_APPKEY[i]);
}
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)setPC1_APPKEY:(Byte [])pC1_APPKEY{
self.PC1_APPKEY = pC1_APPKEY;
}
#end
I need to pass a string from a NSObject class to a UIViewController, I understand that the best way is delegation but the delegate method isn't being called. I'm trying to set the UILabel an DieFacesViewController as the selectedOption from TemporarySelection.
A tableview shows the value of CustomOptionStore, once it's tapped passes its value to TemporarySelection and opens the modal view DieFacesViewCountroller which should, at least in my mind, take the label value from TemporarySelection. The reason I created TemporarySelection is because the DieFacesViewController will be used by other classes, not only by CustomOptionStore, and it will need to load the label from all those classes when different tableViews are selected.
I tried to set the delegate as self in both viewDidLoad and viewWillAppear with no luck, I don't understand if the view loads before being able to call the delegate method or if there's something wrong the way I set the method up.
I've been stuck here for two days, this is the first time I post a question so please forgive me if it's a bit confused.
my delegator class TemporarySelection.h is
#import <Foundation/Foundation.h>
#import "CustomOptionsStore.h"
#class DieFacesViewController;
#protocol TemporarySelectionDelegate <NSObject>
-(void)sendSelection;
#end
#interface TemporarySelection : NSObject
#property (nonatomic, weak) id <TemporarySelectionDelegate> delegate;
#property (nonatomic, strong) NSString *selectedOption;
-(void)addSelection: (CustomOptionsStore *) selection;
#end
and my TemporarySelection.m is
#import "TemporarySelection.h"
#implementation TemporarySelection
-(void)addSelection: (CustomOptionsStore *) selection{
self.selectedOption = selection.description;
[self.delegate sendSelection];
}
#end
the delegate class DiewFacesViewController.h is
#import <UIKit/UIKit.h>
#import "SelectedStore.h"
#import "TemporarySelection.h"
#interface DieFacesViewController : UIViewController <TemporarySelectionDelegate>
#property (strong, nonatomic) IBOutlet UILabel *SelectionName;
#end
and the DieFacesViewController.m is
#import "DieFacesViewController.h"
#interface DieFacesViewController ()
#end
#implementation DieFacesViewController
- (void)viewDidLoad {
TemporarySelection *ts = [[TemporarySelection alloc]init];
ts.delegate = self;
[super viewDidLoad];
}
-(void)sendSelection{
TemporarySelection *ts = [[TemporarySelection alloc]init];
self.SelectionName.text = ts.selectedOption;
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
}
You are not setting the delegate object properly.Check the above code
#import "DieFacesViewController.h"
#interface DieFacesViewController ()<TemporarySelectionDelegate>
{
//global object
TemporarySelection *ts;
}
#end
#implementation DieFacesViewController
- (void)viewDidLoad {
ts = [[TemporarySelection alloc]init];
ts.delegate = self;
[super viewDidLoad];
}
-(void)sendSelection{
//Use the object to extract
self.SelectionName.text = ts.selectedOption;
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
}
I am developing application for iOS7 in xcode 5. I have a view controller ADMSViewController
The .h file is as follows
#import <UIKit/UIKit.h>
#import "IMTWebView.h"
#interface ADMSViewController : UIViewController <UIWebViewDelegate,IMTWebViewProgressDelegate>
{
NSString *barcode;
NSString *vinNumber;
NSTimer *timer;
}
#property (nonatomic,retain) IBOutlet UIWebView *webView;
#property (nonatomic,retain) IBOutlet UIProgressView *progressView;
#end
The .m file is as follows
#import "ADMSViewController.h"
#import <QuartzCore/QuartzCore.h>
#implementation ADMSViewController
#synthesize webView;
#synthesize progressView;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://google.com/"]]];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
- (void)webView:(IMTWebView *)_webView didReceiveResourceNumber:(int)resourceNumber totalResources:(int)totalResources {
[self.progressView setProgress:((float)resourceNumber) / ((float)totalResources)];
if (resourceNumber == totalResources) {
_webView.resourceCount = 0;
_webView.resourceCompletedCount = 0;
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.webView = nil;
self.progressView = nil;
}
#end
The IMTWebview.h file is as follows
#import <UIKit/UIKit.h>
#class IMTWebView;
#protocol IMTWebViewProgressDelegate <NSObject>
#required
- (void) webView:(IMTWebView*)webView didReceiveResourceNumber:(int)resourceNumber totalResources:(int)totalResources;
#end
#interface IMTWebView : UIWebView {
}
#property (nonatomic, assign) int resourceCount;
#property (nonatomic, assign) int resourceCompletedCount;
#property (nonatomic, assign) id<IMTWebViewProgressDelegate> progressDelegate;
#end
the IMTWebCiew.m file is as follows
#import "IMTWebView.h"
#interface UIWebView ()
-(id)webView:(id)view identifierForInitialRequest:(id)initialRequest fromDataSource:(id)dataSource;
-(void)webView:(id)view resource:(id)resource didFinishLoadingFromDataSource:(id)dataSource;
-(void)webView:(id)view resource:(id)resource didFailLoadingWithError:(id)error fromDataSource:(id)dataSource;
#end
#implementation IMTWebView
#synthesize progressDelegate;
#synthesize resourceCount;
#synthesize resourceCompletedCount;
-(id)webView:(id)view identifierForInitialRequest:(id)initialRequest fromDataSource:(id)dataSource
{
[super webView:view identifierForInitialRequest:initialRequest fromDataSource:dataSource];
return [NSNumber numberWithInt:resourceCount++];
}
- (void)webView:(id)view resource:(id)resource didFailLoadingWithError:(id)error fromDataSource:(id)dataSource {
[super webView:view resource:resource didFailLoadingWithError:error fromDataSource:dataSource];
resourceCompletedCount++;
if ([self.progressDelegate respondsToSelector:#selector(webView:didReceiveResourceNumber:totalResources:)]) {
[self.progressDelegate webView:self didReceiveResourceNumber:resourceCompletedCount totalResources:resourceCount];
}
}
-(void)webView:(id)view resource:(id)resource didFinishLoadingFromDataSource:(id)dataSource
{
[super webView:view resource:resource didFinishLoadingFromDataSource:dataSource];
resourceCompletedCount++;
if ([self.progressDelegate respondsToSelector:#selector(webView:didReceiveResourceNumber:totalResources:)]) {
[self.progressDelegate webView:self didReceiveResourceNumber:resourceCompletedCount totalResources:resourceCount];
}
}
#end
My issue is that the progress bar is not animating in the webview. Please help me as I am a newbie to ios development. If there is any other method to implement the same, do inform me.
Thank you in advance for your answers.
For this kind of thing, you can only really 'detect' page size by using Content-Length headers, but otherwise you can still present a loading control (like one of the moving zebra crossing type bars which doesn't show a discrete % progress but shows that activity is occurring.. or even just a UIActivityIndicator). You could try a ready-made class like http://allseeing-i.com/ASIHTTPRequest/ASIWebPageRequest too, which CAN show progress. The author states:
ASIWebPageRequests do not currently support progress tracking for an entire request with its external resources. However, progress updates from external resource requests are passed on to your delegate, so with a bit of work it may be possible to implement this yourself.
I have created a very basic application using the Utility Application template in Xcode 4.2 in which I want an integer variable obtained from a slider or text field in my FlipsideViewController available in my MainViewController.
I have been searching for hour on global variables but can't find a nice simple answer that works for my specific case.
Please help
(note: I am very new at developing for IOS and objective C. Dumb your answer down for me as much as you are capable!)
Thanks a lot
The following is a basic version of my code showing what I want to do.
FlipSideViewController.h
#import <UIKit/UIKit.h>
#class FlipsideViewController;
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
#interface FlipsideViewController : UIViewController
#property (weak, nonatomic) id <FlipsideViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
- (IBAction)sliderChange:(id)sender;
#property (weak, nonatomic) IBOutlet UILabel *sliderValueOnFlipside;
#end
FlipSideViewController.m
#import "FlipsideViewController.h"
#interface FlipsideViewController ()
#end
#implementation FlipsideViewController
#synthesize sliderValueOnFlipside;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[self setSliderValueOnFlipside:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark - Actions
- (IBAction)done:(id)sender
{
[self.delegate flipsideViewControllerDidFinish:self];
}
- (IBAction)sliderChange:(id)sender {
UISlider *slider = (UISlider *) sender;
int var = [slider value];
sliderValueOnFlipside.text = [NSString stringWithFormat:#"Slider Value is %d",var];
}
#end
MainViewController.h
#import "FlipsideViewController.h"
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate>
- (IBAction)showInfo:(id)sender;
#property (weak, nonatomic) IBOutlet UILabel *sliderValueOnMain;
#end
MainViewController.m
#import "MainViewController.h"
#interface MainViewController ()
#end
#implementation MainViewController
#synthesize sliderValueOnMain;
- (void)viewDidLoad
{
[super viewDidLoad];
sliderValueOnMain.text = [NSString stringWithFormat:#"Slider Value from flipside is %d", var];
}
- (void)viewDidUnload
{
[self setSliderValueOnMain:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark - Flipside View
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)showInfo:(id)sender
{
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideViewController" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
}
#end
I can easily get the value of the slider to be displayed on the flipside view however I also want that value displayed on the main view.
Global variables are generally frowned upon in polite programming circles.
If you want a method in MainViewController to react to a change in state in FlipsideViewController, then you could make MVC a delegate of FVC, and have FVC call a method on MVC when the value changes.
There's a good explanation of the delegate design pattern here: http://mobiledevelopertips.com/objective-c/the-basics-of-protocols-and-delegates.html
I have a UILabel(descriptionOfProgram) on a second ViewController(GraphViewController) that needs to be set when the segue from the original MVC occurs.
Currently, in my main MVC, I do two things in my prepareForSegue::
I set an #property NSString in GraphVewController to the string I want it to be.
I set descriptionOfProgram's text to be equal to that string by calling a function in GraphViewController setDescriptionLabel:.
When graphViewController comes on string, the text is not in the label. During testing, I created a button called test in GraphViewController to call setDescriptionLabel when pressed. This worked. Any ideas on what's going on?
I included GraphViewController.h and .m in the second MVC, and GraphingCalculatorViewController.m in the Main MVC.
GraphViewController.h:
//
// GraphViewController.h
// GraphingCalculator
//
// Created by Graham Gaylor on 3/1/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface GraphViewController : UIViewController
#property (nonatomic,copy) NSArray *program;
#property (nonatomic,weak) NSString *description;
#property (weak, nonatomic) IBOutlet UILabel *descriptionOfProgram;
- (IBAction)test:(id)sender;
- (void)setDescriptionLabel:(NSString *)description;
#end
GraphViewController.m:
//
// GraphViewController.m
// GraphingCalculator
//
// Created by Graham Gaylor on 3/1/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "GraphViewController.h"
#import "GraphView.h"
#interface GraphViewController() <GraphViewDataSource>
#property (nonatomic, weak) IBOutlet GraphView *graphView;
#end
#implementation GraphViewController
#synthesize program = _program;
#synthesize descriptionOfProgram = _descriptionOfProgram;
#synthesize description = _description;
#synthesize graphView = _graphView;
- (void)setProgram:(NSArray *)program
{
_program = program;
[self.graphView setNeedsDisplay]; // any time our Model changes, redraw our View
self.graphView.dataSource = self; // setting graphView delegate GraphVC
}
- (IBAction)test:(id)sender {
self.descriptionOfProgram.text = #"test";
[self setDescriptionLabel:self.description];
}
- (void)setDescriptionLabel:(NSString *)description
{
NSLog(#"Got into setDescriptionLabel");
self.descriptionOfProgram.text = #"hello";
}
- (NSArray *)programForGraphView:(GraphView *)sender {
return self.program;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)viewDidUnload {
[self setDescriptionOfProgram:nil];
[super viewDidUnload];
}
#end
This is my main MVC. I got rid of all the extra functions that don't deal with the seque.
GraphingCalculatorViewController.m:
//
// GraphingCalculatorViewController.m
// GraphingCalculator
//
// Created by Graham Gaylor on 3/1/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "GraphingCalculatorViewController.h"
#import "GraphViewController.h"
#interface GraphingCalculatorViewController()
#property (nonatomic,strong) NSArray *programToGraph;
#end
#implementation GraphingCalculatorViewController
#synthesize programToGraph = _programToGraph;
- (void)setAndShowGraph:(NSArray *)program {
self.programToGraph = program;
[self performSegueWithIdentifier:#"ShowGraph" sender:self];
NSLog(#"setAndShowGraph");
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:#"ShowGraph"]) {
[segue.destinationViewController setProgram:self.programToGraph]; // sets GraphVC's program to current program
[segue.destinationViewController setDescriptionLabel:[CalculatorBrain descriptionOfProgram:self.programToGraph]];
NSLog(#"prepareForSegue");
}
}
- (IBAction)graphPressed {
[self setAndShowGraph:self.brain.program];
}
- (void)viewDidUnload {
[self setVariablesUsed:nil];
[super viewDidUnload];
}
#end
prepareForSegue: is called before viewDidLoad: so your IBOutlet will be nil. Try setting the incoming value to a NSString and then use that string to populate the label on viewDidLoad: