I am using following code to set the text of a UILabel in SViewController, From another ViewController FViewController
SViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SViewController"];
[vc setTextForLabel:[NSNumber numberWithInt:1];];
[self.navigationController pushViewController:vc animated:YES];
The setTextForLabel method:
-(void) setTextForLabel: (NSNumber *)text {
textLabel = [[UILabel alloc] init];
[textLabel setText:[NSString stringWithFormat:#"%#",[text stringValue]]];
NSLog(#"The text is %#", textLabel.text);
}
I have declared the property for textLabel in .h file is as follows:
#property (nonatomic, retain) IBOutlet UILabel *textLabel;
And I have also set the IBOutlet in storyboard.
Now in console I see "The text is 1", but the UI is not showing anything!
What am I doing wrong?
remove this line
textLabel = [[UILabel alloc] init];
Also, you need to link the UILabel on interface to your #property (nonatomic, retain) IBOutlet UILabel *textLabel;
Or you may add this label manually to view
textLabel = [[UILabel alloc] init];
[textLabel setText:[NSString stringWithFormat:#"%#",[text stringValue]]];
[self.view addSubView:textLabel];
First of all go put
[vc setTextForLabel:[NSNumber numberWithInt:1]];
after you push the vc.
In your xib/storyboard if your label has something written in it, remove it, leave it blank.
If that doesn't work ... leave the setText method before the push one (as you wrote it initialy) and create a NSNumber member that will hold your value and apply it in viewDidAppear like so
-(void) setTextForLabel: (NSNumber *)text{
numberValue = text; // declared in .h as NSNumber *numberValue (only make it a property if you need acces to it from outside your class)
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated]; //this is important
[textLabel setText:[NSString stringWithFormat:#"%#",[numberValue stringValue]]];
}
Your problem is linked to the view lifecycle of SViewController. When you call [.. setTextForLabel] you don't know if the controller has loaded its views (And thus your UILabel have a good chance of not being created yet)
What you should do is use a NSString property on your controller, set it with the desire text and assigned it to the UILabel in the viewDidLoad of SViewController.
in SViewController.h
#propery (strong, nonatomic) NSString *textToDisplay;
in SViewController.m
-(void)viewDidLoad
{
[super viewDidLoad];
// Here you know all Outlet are loaded and connected
textLabel.text = textToDisplay
}
I did like this
#import "FViewController.h"
#import "SViewController.h"
#interface FViewController ()
#end
#implementation FViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)do:(id)sender
{
SViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SViewController"];
[self.navigationController pushViewController:vc animated:YES];
[vc setTextForLabel:[NSNumber numberWithInt:1]];
}
// in SViewController.h
#import <UIKit/UIKit.h>
#interface SViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *label;
-(void) setTextForLabel: (NSNumber *)text;
#end
// SViewController.m file
#import "SViewController.h"
#interface SViewController ()
#end
#implementation SViewController
#synthesize label;
- (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) setTextForLabel: (NSNumber *)text{
// label.text = [text stringValue];
NSLog(#"%#",label);
[label setText:[text stringValue]];
}
#end
also check your label properties in storyboard are properly set
Related
I have Xib UIView which is being displayed by my ViewController. The Xib contains an UILabel and an UIButton. My button coats all over my xib and i'm using it to navigate my SecondViewController and i achieve this by delegate methods.
Here's the thing about my label; because my button is transparent, i can show it beneath the button. What i can't do is to change mylabel's text from ViewController.
I did some search and come across a suggestion like this:
is create another .nib file for the subview and put the subview in
there. Then in that .nib file, make the file owner IOSubview. Property
connections will work just fine there. Then just add the subview to
your IOViewController programatically. Just remember to load the nib
file from bundle first.
link : https://stackoverflow.com/a/20294118/1450201
But it doesn't make sense to me because the reason i created the xib at first is to use it more than once. I believe solution to this problem could be much simpler. But how??
This is what my xib looks like:
And here is a github repo link and my code:
https://github.com/TimurAykutYildirim/demoView
ViewController.h
#import <UIKit/UIKit.h>
#import "Mini.h"
#interface ViewController : UIViewController <SelectionProtocol>
#property (weak, nonatomic) IBOutlet Mini *miniView;
#property (weak, nonatomic) IBOutlet UILabel *miniLabel;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.miniView.delegate = self;
}
-(void) isClicked {
NSString * storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self presentViewController:vc animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Mini.h
#import <UIKit/UIKit.h>
#protocol SelectionProtocol;
#interface Mini : UIView
#property (nonatomic, weak) id<SelectionProtocol> delegate;
- (IBAction)btnClick:(id)sender;
#end
#protocol SelectionProtocol <NSObject>
#required
-(void) isClicked;
#end
Mini.m
#import "Mini.h"
#implementation Mini
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[self load];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self load];
}
return self;
}
- (void)load {
UIView *view = [[[NSBundle bundleForClass:[self class]] loadNibNamed:#"Mini" owner:self options:nil] firstObject];
[self addSubview:view];
view.frame = self.bounds;
// ui component properties will be set here
}
- (IBAction)btnClick:(id)sender {
if ([self.delegate conformsToProtocol:#protocol(SelectionProtocol)]) {
[self.delegate isClicked];
}
}
#end
Update your Mini.h to add label outlet to it.
Mini.h
#import <UIKit/UIKit.h>
#protocol SelectionProtocol;
#interface Mini : UIView
#property (nonatomic, weak) id<SelectionProtocol> delegate;
#property (weak, nonatomic) IBOutlet UILabel *miniLabel;
- (IBAction)btnClick:(id)sender;
#end
#protocol SelectionProtocol <NSObject>
#required
-(void) isClicked;
#end
and in ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.miniView.delegate = self;
self.miniView.miniLabel.text = //set whatever value
}
i have 2 view controllers:
StackTableViewController.m:
#interface StackTableViewController () <NSFetchedResultsControllerDelegate>
#property (nonatomic, strong) NSFetchedResultsController *fetchedResultController;
#end
#implementation StackTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.fetchedResultController performFetch:nil];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
Target *record = [self.fetchedResultController objectAtIndexPath:indexPath];
self.currentTarget = record.body;
}
HomeViewController.m
#import "HomeViewController.h"
#import "CreateViewController.h"
#import "StackTableViewController.h"
#interface HomeViewController ()
#property (strong, nonatomic) IBOutlet UILabel *targetLabel;
#end
#implementation HomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
StackTableViewController *vc = [[StackTableViewController alloc] init];
NSString *current = vc.currentTarget;
// Do any additional setup after loading the view.
self.targetLabel.text = current;
}
but something wrong with the HomeViewController because it's not populating the label..
how can i solve it?
tnx
You should probably update the label's text within ViewWillAppear of the StackTableViewController
Also, is currentTarget set up in StackTableViewController's init method? If not, it won't be initialized and that would be why you're not getting anything in HomeViewController's label
Explanation
viewDidLoad is not called instead, or before the init! It's called sometime after the init method finishes.
What happens:
- (void)viewDidLoad {
[super viewDidLoad];
StackTableViewController *vc = [[StackTableViewController alloc] init]; // init is called on vc object
NSString *current = vc.currentTarget; // ViewDidLoad was not yet called on vc object!
self.targetLabel.text = current;
}
/// ViewDidLoad will be called on vc object sometime after leaving this method!
What happens is:
You call StackTableViewController *vc = [[StackTableViewController alloc] init]; which sends a message init to the object.
You don't have init method in your implementation so the init of superclass (UIViewController) is called. When you instantiate your ViewController it begins loading view. Only after it's done loading ViewDidLoad will be called.
Please read any article on ViewController's lifecycle .
Solution
Fastest solution to your problem: create a delegate in your table, and inform when it's done loading using delegates, like this:
Table view controller
#implementation StackTableViewController
{
id<TargetChangedDelegate> _myDelegate;
}
-(id)initWithDelegate:(id<TargetChangedDelegate>)delegate
{
_myDelegate= delegate;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.fetchedResultController performFetch:nil];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
Target *record = [self.fetchedResultController objectAtIndexPath:indexPath];
self.currentTarget = record.body;
// inform your delegate
[_myDelegate targetChanged];
}
Home view controller
#interface HomeViewController () <TargetChangedDelegate>
#property (strong, nonatomic) IBOutlet UILabel *targetLabel;
#end
#implementation HomeViewController
- (void)viewDidLoad {
[super viewDidLoad];
StackTableViewController *vc = [[StackTableViewController alloc] initWithDelegate:self];
}
- (void)targetChanged
{
NSString *current = vc.currentTarget;
// Do any additional setup after loading the view.
self.targetLabel.text = current;
}
I have a project that displays a feed of statuses similar to other social networks. Each feed item has several button that do different things. 1 of the buttons opens a new viewcontroller that displays the comments that have been posted on a particular status. When this button is clicked and the view controller is opened i would like it to be a push segue so that their is a back button and the user can navigate back to the feed.
When this button is clicked and the new vc is launched some unique data about the particular status/cell being clicked needs to be sent to the "comments vc ". Where would the code for doing this go?
CUSTOM CELL .H
#import <UIKit/UIKit.h>
#interface FeedItemCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *DefaultImg;
#property (weak, nonatomic) IBOutlet UILabel *NameLabel;
#property (weak, nonatomic) IBOutlet UILabel *StatusLabel;
#property (weak, nonatomic) IBOutlet UILabel *timeLabel;
#property (nonatomic, copy) NSString *msg_id;
#property (nonatomic, copy) NSString *status;
#property (nonatomic, weak) IBOutlet UIButton* commentButton;
#property (nonatomic, weak) IBOutlet UIButton* bumpButton;
#property (strong, nonatomic) id delegate;
-(IBAction)viewComments:(id)sender;
-(IBAction)bump:(id)sender;
#end
#protocol CustomCellProtocol <NSObject>
- (void)EBCellPressed:(NSString *)cellName;
CUSTOM CELL .M
#import "FeedItemCell.h"
#import "CommentsViewController.h"
#import "NSDate+TimeAgo.h"
#interface FeedItemCell() <WYPopoverControllerDelegate>
{
}
- (IBAction)open:(id)sender;
- (void)close:(id)sender;
#end
#implementation FeedItemCell
#synthesize commentButton;
- (instancetype)initWithDelegate:(id)delegate {
self = [super init];
if (self) {
self.delegate = delegate;
// Initialization code
}
return self;
}
-(IBAction)bump:(id)sender{
[self.delegate EBCellPressed:#"NAME"];
}
- (IBAction)open:(id)sender
{
}
#end
publicFeed . M
#import "PublicFeedViewController.h"
#import "FeedItemCell.h"
#import "AFNetworking.h"
#import "UIImageView+WebCache.h"
#import "InboxDetailViewController.h"
#import "SWRevealViewController.h"
#import "CommentsViewController.h"
#import "NSDate+TimeAgo.h"
#interface PublicFeedViewController (){
NSArray *NameLabel;
NSArray *StatusLabel;
NSMutableArray *feedArray;
}
#end
#implementation PublicFeedViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//The below code prompts the user for push notifications. If allowed, code in AppDelegate takes over and stores the token.
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
// Do any additional setup after loading the view.
self.FeedTable.dataSource=self;
self.FeedTable.delegate=self;
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
_sidebarButton.target = self.revealViewController;
_sidebarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = #{#"foo": #"bar"};
[UIApplication sharedApplication].networkActivityIndicatorVisible = TRUE;
[manager POST:#"www" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
//NSLog(#"JSON: %#", responseObject);
self->feedArray = [responseObject objectForKey:#"feed"];
[self.FeedTable reloadData];
[UIApplication sharedApplication].networkActivityIndicatorVisible = FALSE;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return feedArray.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *CellIdentifier=#"Cell";
FeedItemCell *Cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!Cell){
Cell = [[FeedItemCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSLog(#"FEED ARRAY: %#", self->feedArray);
NSDictionary *tempDictionary= [self->feedArray objectAtIndex:indexPath.row];
// Display recipe in the table cell
NSString *thumb_img = [tempDictionary objectForKey:#"thumb_img"];
NSString *thumb_path=#"http://buhzhyve.com/CI_REST_LOGIN/UPLOADS/thumbs/";
NSString *thumb_url = [thumb_path stringByAppendingString:thumb_img];
Cell.NameLabel.text=[tempDictionary objectForKey:#"first_name"];
Cell.StatusLabel.text=[tempDictionary objectForKey:#"message"];
Cell.msg_id=[tempDictionary objectForKey:#"msg_id"];
//Cell.status=[tempDictionary objectForKey:#"message"];
Cell.StatusLabel.lineBreakMode=0;
Cell.StatusLabel.numberOfLines=0;
NSString *commentCount = [tempDictionary objectForKey:#"comment_count"];
NSString *commentButtonText =[NSString stringWithFormat:#"Comments ( %# )",commentCount];
[Cell.commentButton setTitle:commentButtonText forState: UIControlStateNormal];
NSString *bumpCount = [tempDictionary objectForKey:#"bump_count"];
NSString *bumpButtonText =[NSString stringWithFormat:#"Bumps ( %# )",bumpCount];
[Cell.bumpButton setTitle:bumpButtonText forState: UIControlStateNormal];
//[Cell.StatusLabel sizeToFit];
NSString *created_string=[tempDictionary objectForKey:#"created"];
double created_double = created_string.doubleValue;
NSDate *date = [[NSDate alloc] initWithTimeIntervalSince1970:created_double];
NSString *ago = [date timeAgo];
Cell.timeLabel.text=ago;
//Cell.DefaultImg.image = [UIImage imageNamed:#"buhz_mini_logo.png"];
[Cell.DefaultImg setImageWithURL:[NSURL URLWithString:thumb_url]
placeholderImage:[UIImage imageNamed:#"buhz_mini_logo.png"]];
return Cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Ideally you should do lazy loading so that instead of creating a new textView each time, you just reuse the same one.
UITextView *temp = [[UITextView alloc] initWithFrame:CGRectMake(82, 26, self.FeedTable.frame.size.width, 18)]; //This initial size doesn't matter
NSDictionary *tempDictionary= [self->feedArray objectAtIndex:indexPath.row];
NSString *status = [tempDictionary objectForKey:#"message"];
temp.font =[UIFont fontWithName:#"System" size:12];
temp.text = status;
CGFloat textViewWidth = 218;
CGRect tempFrame = CGRectMake(82,26,textViewWidth,18); //The height of this frame doesn't matter.
CGSize tvsize = [temp sizeThatFits:CGSizeMake(tempFrame.size.width, tempFrame.size.height)]; //This calculates the necessary size so that all the text fits in the necessary width.
//Add the height of the other UI elements inside your cell
return tvsize.height + 70;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"commentSegue"]) {
}
}
#end
publicfeed .h
#import <UIKit/UIKit.h>
#interface PublicFeedViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *FeedTable;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *sidebarButton;
- (IBAction)addItem;
#end
So assuming that you're creating this button in code, this is how you could handle this.
This first line tells the button that when it's pressed, it needs to call this specific selector/method sent as the action.
[button addTarget:self action:#selector(showNextViewController) forControlEvents:UIControlEventTouchUpInside];
Then you would create this method in the same class.
- (void) showNextViewController
{
NewViewController *newViewController = [[NewViewController alloc] init]; //Edit this line of course to fit for your situation. I'm not sure if you're loading from an XIB or from a Storyboard, or neither.
newViewController.someVariable = someVariable;
newViewController.someOtherVariable = someOtherVariable;
[[[[[UIApplication sharedApplication] delegate] window] rootViewController].navigationController pushViewController:view animated:YES];
}
This will send the necessary data to the new view controller, and it will also display the new view on the screen with a back button.
Hope this works!
1. Ok so lets pretend this is your custom cell class.
in your .h file of the custom cell you need to add a protocol.
#import <UIKit/UIKit.h>
#interface CustomCell : UIView
#property (strong, nonatomic) id delegate; //this is used for sending messages out of the custom cell
//init
- (id)initWithFrame:(CGRect)frame andCatName:(NSString *)name andDelegate:(id)delegate;
#end
#protocol CustomCellProtocol <NSObject>
-(void)customCellSelected:(NSString *)cellName;
#end
what we actually did is something like creating a custom event that the class can throw out and everyone who subscribes to that can run a method when customCellSelected is thrown.
2. now when you create each custom cell with the init method you need to provide a delegate which kind of points to which class should the custom cell transfer the call to customCellSelected so in the init method you set that delegate.
- (id)initWithFrame:(CGRect)frame andDelegate:(id)delegate {
self = [super initWithFrame:frame];
if (self) {
self.delegate = delegate; //setting which class should be called when calling protocol methods.
// Your initialization code
}
return self;
}
3. now in your .m file of the custom cell, when the user presses your button and you enter your method , let it be buttonPressed
- (IBAction) buttonPressed:(id)sender {
[self.delegate customCellSelected:#"THE CELL'S NAME"]; // calling the protocol method.
}
now the call to the delegate method should be transferred to the vc because when you create the custom cell you use initWithFrame:(CGRect)frame andDelegate:(id)delegate and you transfer self as the delegate , so when [self.delegate customCellSelected:#"THE CELL'S NAME"]; is called it is actually called on the vc.
4. this is how you create the custom cell in the vc:
customCell *tempView = [[customCell alloc] initWithFrame:CGRectMake(X, Y, Width, Height) andDelegate:self]; // here you set the vc as the delegate
5.and now all you have to do is add the method customCellSelected to your vc code so it can called when the customCell is calling it.
- (void)customCellSelected:(NSString *)cellName {
self.selectedCell = cellName;
[self performSegueWithIdentifier:#"SelectedCell" sender:self];
}
6.then add this in the vc:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"SelectedCell"]) {
LevelSelectViewController *levelSelectViewController = (LevelSelectViewController *)segue.destinationViewController;
levelSelectViewController.cellName = self.selectedCell;
}
}
7.only thing you have to remember is to create a segue from your first vc to the second like this:
Can someone please see where I am going wrong with this?
I have a object called Object with a single NSString property.
I then have a MainViewController with a button on it. The button is created programatically and added at runtime.
When yo click this button, it is supposed to set the value of the Object proper to a String, and pass this to the next ViewController.
I manage to set the value of the Object property, but when I call that value to pass it, it is set to null. I have tried many different solutions but nothing seems to work. Can anyone see where my problem lies? I have added all the relevant code below
Object.h
#interface Object : NSObject
#property (nonatomic, strong) NSString *content;
Object.m
#import "Object.h"
#implementation Object
#synthesize content;
Then in MianViewController I create the button and set value of Object property
MainViewController.h
#interface MainViewController : UIViewController
#property (nonatomic, strong) UIButton *myButton;
MainViewController.m
#import "MainViewController.h"
#import "SecondaryViewController.h"
#import "Object.h"
.
.
#synthesize myButton;
- (void)viewDidLoad
{
[super viewDidLoad];
myButton = [UIButton buttonWithType:UIButtonTypeCustom];
myButton.tag = 1;
myButton.frame = CGRectMake(20, 140, 280.f, 40.f);
UIImage *airButton = [UIImage imageNamed:#"gettingHereByAirButton.png"];
[myButton setBackgroundImage:airButton forState:UIControlStateNormal];
[self.view addSubview:myButton];
[myButton addTarget:self action:#selector(myButtonClicked) forControlEvents:UIControlEventTouchUpInside];
}
- (void) myButtonClicked
{
[self performSegueWithIdentifier:#"mySegue" sender:self];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Getting Here...");
Object *object = [[Object alloc] init];
object.content = #"This is the content of the Object";
NSLog(#"Content of Object Set To: %#", object.content);
SecondaryViewController *vc;
vc.object = object;
NSLog(#"Object: %#", object);
NSLog(#"Object.content: %#", object.content);
NSLog(#"ViewController.object.content: %#", vc.object.content);
NSLog(#"Just Did Stuff...");
}
And the SecondaryViewController where the label should be set to that of the Object String
SecondaryViewController.h
#import "Object.h"
#interface SecondaryViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *contentLabel;
#property (nonatomic, strong) Object *object;
SecondaryViewController.m
#synthesize object;
#synthesize contentLabel;
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Content of Object: %#", object.content);
self.contentLabel.text = object.content;
}
And finally a screen grab of my NSLog when the app is running HERE
SecondaryViewController *vc;
Should be
SecondaryViewController *vc = (SecondaryViewController *)segue.destinationViewController;
I have a static library that contains a view controller class.
How on a new project in Xcode after include the static library (and headers) can I call this viewController?
View controller on static library:
#import "VC.h"
#interface VC ()
#property (nonatomic, strong) UILabel *label;
#property (nonatomic, strong) UIWindow *window;
#end
#implementation VC
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_window.backgroundColor = [UIColor whiteColor];
[self.view addSubview: _window];
[super viewDidLoad];
self.label = [[UILabel alloc] initWithFrame:CGRectMake(115.0f, 150.0f, 200.0f, 30.0f)];
self.label.text = #"hello world!";
[self.view addSubview:self.label];
// Do any additional setup after loading the view.
}
#end
I have tried to allocate this ViewController in a new project and call it... but do not work:
VC *vc = [[VC alloc] init];
[self presentViewController:vc animated:YES completion:nil];
Am I missing something else?
* UPDATE
After the last edit, now I can see the viewcontroller, but it's not on top of the main viewcontroller and it becomes black after it loads... any thoughts?
There are a few ways to do this. I would say the most simple way to do this is simply include your viewControllers .xib or storyBoard as files in a folder with the library. If there is no good reason why users cannot have access to this, it shouldn't be that big of an issue.
The other way to do it would be to use the universal framework to make your library. This will return two frameworks for you when you compile it, one with the suffix .framework and the other with the suffix .embeddedframework. The latter will have links to your resources.
The final way to do it is include it in your project as a bundle. This is a somewhat involved and non-intuive process compared to the above ones.
EDIT:
If you are doing it not with a storyboard or .xib file you need to actually alloc and init self.view. It isn't getting loaded in from a storyboard, so you need to load it yourself. That's the issue with this code.
I was missing the basic structure for the view controller.
Creating an UIWindow inside the viewController fixed the problem for me.
Full Source code:
Static library view controller file (VC.m):
#import "VC.h"
#interface VC ()
#property (nonatomic, strong) UILabel *label;
#property (nonatomic, strong) UIButton *button;
#property (nonatomic, strong) UIView *window;
#end
#implementation VC
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// CREATE UIVIEW INSIDE VIEW CONTROLLER
_window = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
_window.backgroundColor = [UIColor whiteColor];
// CREATE BUTTON TO CLOSE VIEW CONTROLLER AFTER IS SHOWN
_button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[_button addTarget:self action:#selector(closeWindow:) forControlEvents:UIControlEventTouchDown];
[_button setTitle:#"Close View" forState:UIControlStateNormal];
_button.frame = CGRectMake(115.0f, 150.0f, 200.0f, 30.0f);
// ADD BUTTON TO THE UIWINDOW
[_window addSubview: _button];
// ADD UIWINDOW TO VIEW CONTROLLER
[self.view addSubview: _window];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Close ViewController
- (IBAction)closeWindow:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
#end
After import the static library and headers to a new app you can invoke the view controller with an IBAction like this:
#import "VC.h" //header for viewcontroller code in static library
...
-(IBAction)callVC:(id)sender {
VC *vc = [[VC alloc] init];
[self presentViewController:vc animated:YES completion:nil];
}