today i have this problem:
Im doing so the title of the First cell of a tableview is show in my "Home" view controller.
This is what i have dun at the moment, but the label in homeviewcontroller is not getting the title text of the first cell.
Reminders.h:
NSMutableString *primerevento;
#property (strong, nonatomic) NSMutableString *primerevento;
Reminders.m:
#synthesize primerevento;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
....
UITableViewCell *cell = (UITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if(indexPath.row == 1){
cell.textLabel.text = primerevento;
}
HomeViewController.h
#property (weak, nonatomic) IBOutlet UILabel *promediototal;
HomeViewController.m
#synthesize promediototal
- (void)viewDidLoad
{
[super viewDidLoad];
....
Reminders *viewsiguiente = [[Reminders alloc] initWithNibName:nil bundle:nil];
promediototal.text = viewsiguiente.primerevento;
[self presentViewController:viewsiguiente animated:YES completion:NULL];
my label on homeviewcontroller appears in blanc, i dont know what im doing wrong, im really trying.
Thanks for your time guys
In the homeViewController don't forget to import the .h of the remindersViewController.
#import "reminders.h"
#property (weak, nonatomic) IBOutlet UILabel *promediototal;
Then in the homeViewController.m where you want your text - promediototal.text = reminders.primerevento.text;
#synthesize promediototal
- (void)viewDidLoad
{
[super viewDidLoad];
....
Reminders *viewsiguiente = [[Reminders alloc] initWithNibName:nil bundle:nil];
promediototal.text = reminders.primerevento.text;
[self presentViewController:viewsiguiente animated:YES completion:NULL];
We have probably still too view code to understand what you are up to.
There is one thing though:
Reminders *viewsiguiente = [[Reminders alloc] initWithNibName:nil bundle:nil];// 1)
promediototal.text = viewsiguiente.primerevento; // 2)
[self presentViewController:viewsiguiente animated:YES completion:NULL]; // 3)
1) What is the purpose of that? Firstyou create a brand new view controller object. As you do not create it from nib (which is fine) it cannot have any poperties set. so viewsiguiente.primerevento is nil at that point of time.
2) Now you take this nil value and assign it to promeditional.text which becomes nil to? What is the sense in that? Did you mean?
viewsiguiente.primerevento = promediototal.text;
3) And now you present the newly created view controller viewsiguiente. You did not make any changes to it. That may be fine if you implementation of Reminders takes care of the views. But you did not set any value from external.
Related
Here's the deal:
I have a UICollectionView which populates itself from an array of objects. I want to be able to tap one of the views representing an object in my UICollection view and be taken to a new view displaying details of the object I selected in the UICollectionView (like the selected object's ID for example).
Unfortunately, whatever I try to set is always null!
Here is the object:
#interface obj : NSObject
#property (nonatomic, strong) NSString *objId;
...
#property (nonatomic, strong) NSString *imageURL;
#end
Here is the main view controller:
#interface ViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
#property (weak, nonatomic) IBOutlet UICollectionView *badgesCollectionView;
#property (strong, nonatomic) NSArray *objArray;
...
#end
Here is the detail view:
#interface DetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *objId;
#end
Here is where I'm trying to populate the detail view (in my main ViewController.m)
// Implement action for object selection
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
DetailViewController *detailView = [[DetailViewController alloc] init];
detailView.objIdLabel.text = [[self.objArray objectAtIndex:indexPath.row] objId];
[self.navigationController pushViewController:detailView animated:YES];
NSLog(#"Object Selection: Report");
NSLog(#"Label Text : %#", detailView.objId.text);
NSLog(#"Id of object : %#", [[self.objArray objectAtIndex:indexPath.row] objId]);
}
When I select an object in UICollectionView, I get a transition to a detailView without anything populated. Here is what's logged:
Object Selection: Report
Label Text : (null)
Id of object : f0f47920-f449-4fd0-a74e-804546905437
Any insight into this would be fantastic. Thanks!
The output of the UILabel's text field is null because the label property is not actually linked to anything until the view is loaded. In this case, it wont happen until after you push the view. In order to get around this, you can just have a property on your DetailViewController that holds the string until the view appears.
Then in viewDidLoad or viewWillAppear in DetailViewController, you can set the text on objIdLabel to the property that contains the string
The problem can come from the DetailViewController implementation.
DetailViewController *detailView = [[DetailViewController alloc] init];
only init the Controller
but you declare
#interface DetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *objId;
#end
wich means you must use a xib.
So you first have to use
DetailViewController *detailView = [[DetailViewController alloc] initWithNibName:#"DetailViewXIBName" bundle:nil];
then try to affect the value to objIdLabel once the controller is pushed:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
DetailViewController *detailView = [[DetailViewController alloc] initWithNibName:#"DetailViewXIBName" bundle:nil];
[self.navigationController pushViewController:detailView animated:YES];
detailView.objIdLabel.text = [[self.objArray objectAtIndex:indexPath.row] objId];
NSLog(#"Object Selection: Report");
NSLog(#"Label Text : %#", detailView.objId.text);
NSLog(#"Id of object : %#", [[self.objArray objectAtIndex:indexPath.row] objId]);
}
You have to affect the text after [super viewDidLoad]; is called.
These are just assumptions as we only have limited information
It may push a blank view controller because you are not strongly holding onto the detailView.
Try adding:
#property (nonatomic, strong) DetailViewController *detailView;
to the main ViewController, then in the didSelectItemAtIndexPath method:
// Implement action for object selection
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
self.detailView = [[DetailViewController alloc] init];
self.detailView.objIdLabel.text = [[self.objArray objectAtIndex:indexPath.row] objId];
[self.navigationController pushViewController:self.detailView animated:YES];
}
It turns out this comes down to a xib's lifecycle. It is true, as many of you suggested, that the detailView is not actually linked with all of the items associated with it (like the objId UILabel) until it's loaded.
I ended up fixing this by creating a new singleton model object to hold onto the selected object. I was then able to set the selected object on the singleton from my main view controller and call it from the detailView to set my objId on ViewDidLoad.
Im building an app that calls different subviews and lay them over in a main view controller (http://imgur.com/p6l9Oac)
when ever the user clicks a button on the bottom part of the screen (lets call it sliding menu!) the view behind it will disappear and new one will show up.
one of the subviews is Settings , which it have some switches to enable/disable some of the buttons.
in the SettingsViewController.
Ive set a protocol:
#protocol SettingsViewControllerDelegate <NSObject>
#required
-(void)hideCountdownView;
-(void)showCountdownView;
#end
and the interface contains:
#interface SettingsHubViewController : UIViewController
#property (weak, nonatomic) IBOutlet UISwitch *enableCountdown;
#property (nonatomic, assign) id <SettingsViewControllerDelegate> delegate;
#property (weak, nonatomic) IBOutlet UIView *mainView;
#end
and in the Implementation:
- (IBAction)switchAction:(id)sender {
if (!self.enableCountdown.on) {
NSLog(#"The view is Hidden");
[_delegate hideCountdownView];
} else if (self.enableCountdown.on) {
NSLog(#"The view is Shown");
[_delegate showCountdownView];
}
}
You can see i used _delegate to use the show and hide functions, I used NSLog to make sure that Im calling the functions correctly.
in the MainViewController
#import "SettingsHubViewController.h"
#interface MainViewController () <SettingsViewControllerDelegate>
#property (nonatomic, strong) SettingsHubViewController * settingsViewController;
and the Implementation
#implementation MainViewController
-(void)showCountdownView {
self.slidingMainMenuViewController.countdownView.hidden = NO;
NSLog(#"Showing Countdown");
}
-(void)hideCountdownView {
self.slidingMainMenuViewController.countdownView.hidden = YES;
NSLog(#"Hiding Countdown");
}
-(void)viewDidLoad {
[super viewDidLoad];
self.settingsViewController.delegate = self;
self.slidingMainMenuViewController.delegate = self;
}
the problem is that the NSLogs above is not being called at all, can any one help me ?
Thanks
UPDATE: Since i have more that 20 different views that needs to be called, i created this method
- (UIView *) getPresentedMenu:(NSString *) menuIdentifer withMenuTag:(int) menuTag withAViewController:(UIViewController*) menuViewController andMenuDelegate:(id) menuDelegate {
menuViewController = [[UIStoryboard storyboardWithName:#"Main" bundle:Nil] instantiateViewControllerWithIdentifier:menuIdentifer];
menuViewController.view.tag = menuTag;
if (self.viewBeingCalledBySwipe == NO) {
menuViewController.view.frame = CGRectMake(0, menuViewController.view.frame.size.height, menuViewController.view.frame.size.width, menuViewController.view.frame.size.height);
} else if (self.isItRightSwipe == YES) {
menuViewController.view.frame = CGRectMake(-menuViewController.view.frame.size.width, 0, menuViewController.view.frame.size.width, menuViewController.view.frame.size.height);
} else if (self.isItRightSwipe == NO) {
menuViewController.view.frame = CGRectMake(menuViewController.view.frame.size.width, 0, menuViewController.view.frame.size.width, menuViewController.view.frame.size.height);
}
[self.view addSubview:menuViewController.view];
[self addChildViewController:menuViewController];
[menuViewController didMoveToParentViewController:self];
UIView *view = menuViewController.view;
return view;
}
So when ever i need a certain view controller, i just call this function
self.childView = [self getPresentedMenu:#"Settings" withMenuTag:SETTINGS_TAG withAViewController:self.settingsViewController andMenuDelegate:self.settingsViewController.delegate];
but this method is not assigning the delegate
If settingsViewController is an IBOutlet, you have to add IBOutlet to it's declaration and connect it using the storyboard or xib.
#property (nonatomic, strong) IBOutlet SettingsHubViewController * settingsViewController;
But if it's not an Outlet, you have to allocate it before set it's delegate.
self.settingsViewController = [[SettingsHubViewController alloc] init];
self.settingsViewController.delegate = self;
You should also verify that your - (IBAction)switchAction:(id)sender IBAction is correctly connected in the storyboard or xib.
When you initialize your SettingsViewController, make sure that you do it using the storyboard method and not [[SettingsViewController alloc] init].
First set a Storyboard ID directly in your storyboard view:
Then use this to settingsViewController:
self.settingsViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:NULL] instantiateViewControllerWithIdentifier:#"SettingsViewController"];
Replace MainStoryboard_iPhone with your Storyboard name.
Hope that helps!
// If u are using View controller
SettingsHubViewController *settingVC = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"yourStoryBoardIdentifier"];
settingVC.delegate = self;
// If u are using XIB load the NIB after that set the settingVC.delegate = self;
its working for me (I created OverLay view and loaded in main class)
I'm a little new to Xcode/app development
I'm currently trying to program 4 static cells in my view controller. However, when I go to run my app, the tableview doesn't show.
Here screenshot of what occurs in the ios simulator:
Here image of my tableview and its attributes in storyboard:
My SettingsViewController.h file:
#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>
#interface SettingsViewController : UIViewController < MFMailComposeViewControllerDelegate>
#property (weak, nonatomic) IBOutlet UIBarButtonItem *sidebarButton;
#end
My SettingsViewController.m file:
#import "SettingsViewController.h"
#import "SWRevealViewController.h"
#interface SettingsViewController ()
#property (nonatomic, strong) NSArray *menuItems;
#end
#implementation SettingsViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_sidebarButton.target = self.revealViewController;
_sidebarButton.action = #selector(revealToggle:);
_sidebarButton.tintColor = [UIColor colorWithWhite:0.1f alpha:0.7f];
// Add pan gesture to hide the sidebar
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
// Do any additional setup after loading the view.
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 0 && indexPath.section == 0){
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://myawesomeapp.com/support"]];
} else if(indexPath.row == 0 && indexPath.section == 1){
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:#"[My Awesome App] Support request"];
[mailViewController setToRecipients:[NSArray arrayWithObject:#"support#myawesomeapp.com"]];
[self presentModalViewController:mailViewController animated:YES];
}
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error{
[self dismissModalViewControllerAnimated:YES];
}
What exactly is the problem?
As far as I am aware static content only works with a UITableViewController as part of a storyboard. Your view controller appears to be a UIViewController subclass instead, so it will not be able to read the information from the storyboard.
I'm not sure how you've managed to get it set up like you have, but it may be possible just to redefine your SettingsViewController as inheriting from a table view controller instead of a plain view controller (you might have to connect the tableView outlet after doing this).
To change the inheritance, change this line of code:
#interface SettingsViewController : UIViewController < MFMailComposeViewControllerDelegate>
To this:
#interface SettingsViewController : UITableViewController < MFMailComposeViewControllerDelegate>
If not, you may have to drag a new table view controller onto the storyboard and set it up again with the static content.
You should adopting the UITableViewDelegate protocol by adding the <UITableViewDelegate> to your .h file.
After that, you need to connect the table view to the relevant .h or .m file and make it the delegate for the relevant table.
Anyway take a brief look at this tutorial..
In the storyboard size inspector, try setting height, width and origin with sufficiently large values. If that makes it visible, then play with auto stretch attributes in the same inspector (sorry, don't remember the exact names).
I am creating an iPad application (iOS6.1) which has a master detail view concept. First view is a table view has list of items that are been loaded from Plist, when each row gets selected the second table view gets loaded with another Plist. theirs is my Detail view which has to display an UIView with a UILabel ans an UIImage. I am using didSelectRowAtIndexPath method . The first two table Views are been displayed properly and loads the row and display corresponding View but the last detail view which is supposed to display the UILabel and an image is empty, can any one help me to solve this problem
My Code for the didSelectRowAtIndexPath method is
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TaskDetailViewController *newTaskDetailViewController = [[TaskDetailViewController alloc] init];
// pass the row to newDetailViewController
if (weekNumber == 0)
{
newTaskDetailViewController.taskdescription = [weeklist1 objectAtIndex:indexPath.row];
}
if (weekNumber == 1)
{
newTaskDetailViewController.taskdescription = [weeklist2 objectAtIndex:indexPath.row];
}
if (weekNumber == 2)
{
newTaskDetailViewController.taskdescription = [weeklist3 objectAtIndex:indexPath.row];
}
// ...... repeated for 39 times because of the list
newTaskDetailViewController.taskNumber = indexPath.row;
[self.navigationController pushViewController:newTaskDetailViewController animated:YES];
}
DetailView header
#import <UIKit/UIKit.h>
#interface TaskDetailViewController : UIViewController
#property int taskNumber;
#property(strong , nonatomic) NSString *taskdescription;
#property (nonatomic , strong) NSMutableDictionary * tasks;
#property (strong, nonatomic) IBOutlet UIImageView *questionImage;
#property (strong, nonatomic) IBOutlet UILabel *displayText;
#end
Implemetation file has
#implementation TaskDetailViewController
#synthesize taskNumber;
#synthesize taskdescription;
#synthesize tasks;
#synthesize displayText;
#synthesize questionImage;
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = taskdescription;
NSLog(#"%#", taskdescription);
}
Your problem is using alloc init to create an instance of TaskDetailViewController. You've created that controller in the storyboard so you should instantiate it from the storyboard using an identifier that you give it (DetailViewController in my example):
TaskDetailViewController *newTaskDetailViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
Ok, so I have tried this a lot of different ways...
At the moment I have placed the UINavigationBar with the IB. Then declared it with IBOutlet.
From there I can't seem to change the title no matter what i try. Even just in ViewDidLoad.
Also, I dont need to assign the delegate of the navbar do i?
Here is my code:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController < UITableViewDataSource, UITableViewDelegate>
{
NSArray *myArrayOne;
NSArray *myArrayTwo;
UITextView *myTextView;
UINavigationBar *myNavBar;
}
#property (nonatomic, retain) NSArray *myArrayOne;
#property (nonatomic, retain) NSArray *myArrayTwo;
#property (nonatomic, retain) IBOutlet UITextView *myTextView;
#property (nonatomic, retain) IBOutlet UINavigationBar *myNavBar;
#end
and:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
//Synthesising anything with a property call in the .h file.
#synthesize myArrayOne;
#synthesize myArrayTwo;
#synthesize myTextView;
#synthesize myNavBar;
- (void)viewDidLoad
{
//declaring and instantiating datapaths and also
// reading into arrays from plist.
NSString *datapath1 = [[NSBundle mainBundle] pathForResource:#"myListOne" ofType:#"plist"];
NSString *datapath2 = [[NSBundle mainBundle] pathForResource:#"myListTwo" ofType:#"plist"];
myArrayOne = [[NSArray alloc] initWithContentsOfFile:datapath1];
myArrayTwo = [[NSArray alloc] initWithContentsOfFile:datapath2];
self.navigationItem.title = #"Hi";
[super viewDidLoad];
}
#pragma mark - TableView Delegate stuff
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//myNavBar.title = [myArrayOne objectAtIndex:indexPath.row];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
#pragma mark - TableView Datasource stuff
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//returns amount of items inside myArrayOne as amount of rows
return [myArrayOne count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *myCell = nil;
myCell = [tableView dequeueReusableCellWithIdentifier:#"myReuseCell"];
if (myCell == nil)
{
myCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myReuseCell"];
}
myCell.textLabel.text = [myArrayOne objectAtIndex:indexPath.row];
return myCell;
}
#end
the actual code to change the title is just one way i have tried...
Any other way? And do I need to link the navigationbar in the IB with anything?
If you have a navigation bar without a navigation controller, you have to give it a stack (in your case, a stack of one) navigation items.
In viewDidLoad of your view controller, add your view controller's navigation item to the stack:
self.myNavBar.items = #[self.navigationItem];
Now you can set the title like so:
self.navigationItem.title = #"Hello";
and it will appear in your navigation bar.
The solution above by jrturton works fine UNLESS you also have a UIBarButtonItem (e.g. a "Done" button) in the UINavigationBar. In that case, the proposed solution causes the UIBarButtonItem to disappear.
Here's how to do it in a way that lets you change the UINavigationBar title but also preserve the UIBarButtonItem:
Add IBOutlet UINavigationItem *myNavigationItem; to your code.
In IB, in the outline view (not the storyboard view), right click the containing UIViewController and drag to the UINavigationItem that was automatically created by IB inside the UINavigationBar and connect to myNavigationItem.
Back in your code, add self.myNavigationItem.title = #"Hello";
I think you need to have a navigationController instead why don't you check this link:
create navigation bar for tableView programmatically in objective-C
and if you already have a navigation controller in your app delegate, then you should remove the IBoutlet you've created then use:
self.navigationItem.title = #"Hi";
for this will be referring the navigationController in your app delegate.