NameSubViewController and NameSubView are added in ViewController.m:
#import "NameSubViewController.h"
#import "NameSubView.h"
...
- (void)viewDidLoad
{
[super viewDidLoad];
NameSubViewController *nameController = [[NameSubViewController alloc] initWithNibName:#"NameSubViewController" bundle:nil];
NameSubView *nameSubView = (NameSubView *)[nameController view];
}
But I want to make properties for them so I can access them from every part of the view. What to write in ViewController.h to declare the properties there instead?
.h
#property (nonatomic, retain) NameSubView *nameSubView;
.m
under line #implementation
#synthesize nameSubView;
Related
I have a little trouble with my delegate example. I created a very simple code to learn how delegates work. I know that my delegate not will be called but i can't figure out why?
So here is the complete code. Please tell me what i do wrong. It is really important for me to understand the error in this code.
First Viewcontroller: h.file
#import <UIKit/UIKit.h>
#protocol ViewControllerDelegate;
#interface ViewController : UIViewController
#property (nonatomic, retain) id<ViewControllerDelegate> delegate;
#end
#protocol ViewControllerDelegate <NSObject>
- (void)transfer:(ViewController *)data number:(NSUInteger)value;
#end
First Viewcontroller: m.file
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize delegate;
- (void)viewDidLoad
{
[super viewDidLoad];
if ([delegate respondsToSelector:#selector(transfer:number:)]){
[delegate transfer:self number:65];
NSLog(#"delegate called");
}
[delegate transfer:self number:65]; //Try to call without if-statement.
}
#end
SecondViewcontroller: h.file
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface SecondViewController : UIViewController <ViewControllerDelegate>
#end
SecondViewcontroller: m.file
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (void)transfer:(ViewController *)data number:(NSUInteger)value
{
NSLog(#"received information from ViewController");
}
- (void)viewDidLoad
{
[super viewDidLoad];
ViewController *viewcontroller = [[ViewController alloc] init];
viewcontroller.delegate = self;
}
#end
In the storyboard i use two container views so both ViewControllers will shown.
Your current code is fine. The problem appears to be that you are never loading the view controllers view(s) so the viewDidLoad method isn't being called.
To test, push the viewcontroller, or just request viewcontroller.view.
I have rewritten this to try and make it more descriptive with more code hopefully:
I have set up a separate UIView class called: pageTitleView code below:
header file:
#import <UIKit/UIKit.h>
#interface pageTitleView : UIView
#property (nonatomic, strong) IBOutlet UILabel *pageTitle;
#property (nonatomic, strong) IBOutlet UILabel *subTitle;
#end
The M File:
#implementation pageTitleView
#synthesize pageTitle;
#synthesize subTitle;
- (id)initWithFrame:(CGRect)frame{
pageTitle = [[UILabel alloc] initWithFrame:CGRectMake(0,labelPosY,300,20)];
pageTitle.textColor = txtColour;
pageTitle.backgroundColor = [UIColor clearColor];
pageTitle.textAlignment = NSTextAlignmentCenter;
pageTitle.font = [UIFont systemFontOfSize:14];
// pageTitle.text to be set by parent view
[self addSubview:pageTitle];
}
With in my parent view controller I have the following:
The Header File:
#import <UIKit/UIKit.h>
#interface UsingThisGuide : UIViewController
#property (strong, nonatomic) UIView *PageTitleBlock;
#property (strong, nonatomic) UIWebView *dispalyPageContent;
#property (strong, nonatomic) UIView *FooterBar;
#end
In the M file i have the following:
#import <QuartzCore/QuartzCore.h>
#import "pageTitleView.h"
#import "MyFirstView.h"
#interface MyFirstView ()
#end
#implementation MyFirstView {
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad {
_PageTitleBlock = [[pageTitleView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
_PageTitleBlock.layer.cornerRadius = 5;
_PageTitleBlock.pageTitle.text = #"This should work but not";
[self.view addSubview:_PageTitleBlock];
[super viewDidLoad];
}
#end
No what i want to do is set the pageTitle.text from the pageTitleView class via its parent controller MyFirstView using something like _PageTitleBlock.pageTitle.text= but this is the error i am getting:
Property 'pageTitle' not found on object of type 'UIView *
Yes, you can do that easily, for example, using properties.
In header file of TitleBlock (or pageTitleView) class in #interface section before #end you should define property:
#property (nonatomic, retain) UILabel pageTitle;
or for ARC-projects
#property (nonatomic, strong) UILabel pageTitle;
In parent view controller you should initiate _PageTitleBlock with frame:
_PageTitleBlock = [[pageTitleView alloc] initWithFrame:CGRectMake(10, 10, 200, 200)]; // specify needed frame
// and add it to root view:
[self.view addSubview:_PageTitleBlock];
Now you could access pageTitle property:
_PageTitleBlock.pageTitle.text = #"Text of page title label";
Hope it will help you.
P.S. For class names it is better to use сapitalized names, i.e., PageTitleView rather then pageTitleView.
The problem here, is that you are declaring your property called PageTitleBlock of type UIView in UsingThisGuide, but then call pageTitle which is declared in the class pageTitleView. The compiler doesn't trust this.
Change the type of PageTitleBlock from UIView to pageTitleView and you're good to go!
I'm trying to call a method from another class with a simple button in my storyboard.
Here are my files:
ViewController.m
// ViewController.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "PrintHello.h"
#interface ViewController : UIViewController <NSObject>{
PrintHello *printMessage;
}
#property (nonatomic, retain) PrintHello *printMessage;
#end
ViewController.m
// ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize printMessage;
- (void)viewDidLoad{
[super viewDidLoad];
NSLog(#"ViewDidLoad loaded");
}
- (IBAction)Button01:(id)sender{
self.printMessage = [[PrintHello alloc] init]; // EDIT: THIS LINE WAS MISSING NOW IT WORKS
[self.printMessage Print];
NSLog(#"Button01 Pressed");
}
#end
PrintHello.h
// PrintHello.h
#import <Foundation/Foundation.h>
#interface PrintHello : NSObject
-(void) Print;
#end
PrintHello.m
// PrintHello.m
#import "PrintHello.h"
#implementation PrintHello
-(void)Print{ NSLog(#"Printed");}
#end
And also in the storyBoard there is a Button01 linked to the Viecontroller.
From the Log i know that:
viewDidLoad is loaded
and the button is pressed when is pressed :)
BUT the method Print is not called?
Where am i doing wrong?
Before you call [self.printMessage Print];, I think you need to put self.printMessage = [[PrintHello alloc] init];.
As woz has said, you haven't initialized printMessage yet, so the object doesn't exist yet! You probably want to initialize it within viewDidLoad of your ViewController.m file, rather than reinitialize the object over and over again within the button click.
-(void)viewDidLoad
{
[super viewDidLoad];
self.printMessage = [[PrintHello alloc] init];
NSLog(#"ViewDidLoad loaded");
}
I know this is just a fundamental question but still somewhere I am missing something, I am playing with passing data to a textView from another class. For this I have created two classes one with xib file (ViewController) and another without(secondVC).
What I am trying to do is that I have a textview in ViewController class and wanted to pass the data to this textView from secondVC. This is how I am doing.
//ViewController.h
#import <UIKit/UIKit.h>
#import "secondVC.h"
#interface ViewController : UIViewController{
IBOutlet UITextView *textView;
}
#property (nonatomic, retain) UITextView *textView;
- (IBAction)go:(id)sender;
#end
//ViewController.m
- (IBAction)go:(id)sender{
secondVC *sec = [[secondVC alloc] init];
[sec print];
}
//secondVC.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface secondVC : UIViewController
- (void)print;
#end
//secondVC.m
- (void)print{
NSString *printThis = #"This works";
ViewController *vc = [[ViewController alloc] init];
[vc.textView setText:printThis];
//vc.textView.text = printThis //Tried both
}
Any suggestions would be appreciated.
Thanks
you can do like this :
//ViewController.h
#import <UIKit/UIKit.h>
#import "secondVC.h"
#interface ViewController : UIViewController{
IBOutlet UITextView *textView;
}
#property (nonatomic, retain) UITextView *textView;
- (IBAction)go:(id)sender;
#end
//ViewController.m
- (IBAction)go:(id)sender{
secondVC *sec = [[secondVC alloc] init];
sec.viewController = self;
[sec print];
}
//secondVC.h
#import <UIKit/UIKit.h>
#import "ViewController.h"
#interface secondVC : UIViewController {
ViewController *viewController;
}
#property(nonatomic, retain)ViewController *viewController;
- (void)print;
#end
//secondVC.m
#synthesize viewController;
- (void)print{
NSString *printThis = #"This works";
self.viewController.textView.text = printThis ;
}
Try with protocol... if you want to send string from textView(child) to other ViewController(parent)
You need a delegate method that is fired from the SecondVC and handled in the first one (ViewController).
There are a few issues here:
You've got a ViewController creating a new secondVC and sending it a print message. That's okay, but the implementation of -print creates a different instance of ViewController and tries to set the text of it's textView property. That's clearly not what you want -- you should instead be sending the text back to the original instance of ViewController.
That second instance of ViewController very likely has its textView property set to nil since textView is an outlet, but you haven't loaded its view from the .xib.
It's really not nice for one view controller to mess with the views of another view controller. The secondVC should be giving the text to the original ViewController object, not trying to set the text of one of its views.
To facilitate communication from secondVC to ViewController, give secondVC a property to keep track of the original ViewController. The usual thing to do here is to define a delegate protocol for secondVC and implement that protocol in ViewController. When ViewController creates secondVC, it sets the delegate of secondVC to itself. That gives secondVC a pointer to its delegate (it shouldn't care whether its a ViewController or some other kind of object, as long as the delegate implements the right methods).
.h file:
#import <UIKit/UIKit.h>
#protocol StringDelegate <NSObject>
-(void)getArrayOfStrings:(NSMutableArray*)strArray;
#end
#interface WWSettings : UIViewController{
}
#property(nonatomic,assign)id<StringDelegate>delegate;
#end
.m file:
#import "WWSettings.h"
#implementation WWSettings
#synthesize delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void)blablablaFunction{
[delegate getArrayOfStrings:yourArray];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
#end
if you dont understand how it works .. ask ! i'll make my best to help you )
your secondVC
#import <UIKit/UIKit.h>
#import "WWSettings.h"
#interface secondVC : UIViewController<StringDelegate>{
WWSettings *obj;
}
#end
and .m file :
#import "secondVC.h"
#implementation secondVC
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void)getArrayOfStrings:(NSMutableArray *)strArray{
// here you get your array !!! it's a delegate function made by you in child viewController;
}
- (void)viewDidLoad
{
obj = [[WWSettings alloc]init];
[obj setDelegate:self];
[super viewDidLoad];
// Do any additional setup after loading the view.
}
first VC .h file :
#import <UIKit/UIKit.h>
#protocol textViewChildDelegate <NSObject>
-(void)getStrings:(NSString*)string;
#end
#interface textViewChild : UIViewController<UITextViewDelegate>{
UITextView *textView;
}
#property(nonatomic,assign)id<textViewChildDelegate>delegate;
#end
.m file:
#import "textViewChild.h"
#implementation textViewChild
#synthesize delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void)myWorkingMethod{
// get string from textView
[delegate getStrings:textView.text];
}
- (void)viewDidLoad
{
textView = [[UITextView alloc]initWithFrame:CGRectMake(0, 240, 320, 240)];
[super viewDidLoad];
// Do any additional setup after loading the view.
}
Now go to secondVC .h:
#import <UIKit/UIKit.h>
#import "textViewChild.h"
#interface TextViewViewController : UIViewController<textViewChildDelegate>{
UITextView * myfirstTextView;
}
#end
and to .m file:
#import "TextViewViewController.h"
#implementation TextViewViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)getStrings:(NSString *)string{
myfirstTextView.text = string; // finally we get string from child view controller
}
- (void)viewDidUnload
{
myfirstTextView = [[UITextView alloc]init];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
I'm getting the error mentioned in the title.
Here's my interface:
#import <UIKit/UIKit.h>
#class ControllerLevel1;
#interface RootController : UIViewController {
ControllerLevel1 *controllerLevel1;
}
#property (retain, nonatomic) ControllerLevel1 *controllerLevel1;
#end
And here's the implementation:
#import "RootController.h"
#import "ControllerLevel1.h"
#implementation RootController
#synthesize controllerLevel1;
- (void)viewDidLoad {
ControllerLevel1 *firstLevel = [[ControllerLevel1 alloc]initWithNibName:#"ControllerLevel1" bundle:nil];
self.controllerLevel1 = firstLevel;
[self.view insertSubview:firstLevel.view atIndex:0];
[firstLevel release];
[super viewDidLoad];
}
The error occurs in [self.view insertSubview:firstLevel.view atIndex:0];
It's complaining about firstLevel.view.
So, likely you didn't declare "view" as a property in ControllerLevel1.h. Show us the .h file for that and we can help more.