View Controller Not Displaying Details - ios

I have an app here that asks for user input for 3 fields. After the 3 fields are entered, they are displayed in a view controller inside of a custom cell. You can add as many of these events as you like. You can then choose to click on an event cell to display the information in a new view controller about that specific event. For some reason, the details for the events I have entered are not showing up at all. I just get a blank controller screen. I can't seem to figure out why, but I thought I had the code correctly implemented in this controller. Does it have to do with my creation of a new Event object "theEvent"?
Here is some of my code (the full project will be linked below):
Full Project: Full Project Link Removed
FinalDetailViewController.h
#import <UIKit/UIKit.h>
#class Event;
#interface FinalDetailViewController : UITableViewController
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) Event *event;
#property (weak, nonatomic) IBOutlet UILabel *detailLabel;
#property (weak, nonatomic) IBOutlet UILabel *locationLabel;
#property (weak, nonatomic) IBOutlet UILabel *dateTimeLabel;
#end
FinalDetailViewController.m
#import "FinalDetailViewController.h"
#import "Event.h"
#interface FinalDetailViewController ()
- (void)configureView;
#end
#implementation FinalDetailViewController
#pragma mark - Managing the detail item
- (void)configureView
{
Event *theEvent = self.event;
static NSDateFormatter *formatter = nil;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"CCCC, MMMM dd, yyyy hh:mm a"];
}
if (theEvent) {
self.detailLabel.text = theEvent.detail;
self.locationLabel.text = theEvent.location;
self.dateTimeLabel.text = [formatter stringFromDate:(NSDate *)theEvent.date];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

It looks like you intended to make the FinalDetailViewController's table be a static table view (since you're making outlets to the labels, which you can only do in a static table). Change the table view to static cells, and it should work.

Related

exc_bad_access code=1 when loading UIView

I have an app where I need to present an overlay for feedback. I started by simply creating the exact thing I wanted within the UIViewController I wanted. However this presents to 2 problems. 1) I can't reuse this in another view (As I need to now) and 2) Because it's an overlay, it covers the entire UIViewController on the storyboard so I can't see the controls beneath it.
I looked at moving to an external UIView .xib file and loading dynamically which worked great, except whatever I did, I couldn't never get a handle on the labels within the nib to update the text.
Then I decided that making it a class and creating a delegate method for it would probably be the best way forward.
I have created a very simply .xib and laid it out as well as a .h and .m file (overlayView) and wired it all in an it looks good, except when trying to present the overlayView I get a exc_bad_access on the line
[window addSubview:self];
And I can't work out why. Full code below:
overlayView.h
#import <UIKit/UIKit.h>
#class overlayView;
#protocol overlayDelegate;
#interface overlayView : UIView
#property (nonatomic, strong) id <overlayDelegate> delagate;
-(instancetype)initWithTitle:(NSString *)title
dateFrom:(NSString *)dateFrom
dateTo:(NSString *)dateTo
description:(NSString *)description;
#property (strong, nonatomic) IBOutlet UILabel *overlayTitleLbl;
#property (strong, nonatomic) IBOutlet UILabel *overlayDateFromLbl;
#property (strong, nonatomic) IBOutlet UILabel *overlayDateToLbl;
#property (strong, nonatomic) IBOutlet UILabel *overlayDescLbl;
#property (strong, nonatomic) IBOutlet UILabel *overlayIcon;
-(void)showOverlay;
-(void)dismissOverlay;
#end
#protocol overlayDelegate <NSObject>
#optional
#end
overlayView.m
#import "overlayView.h"
#import "NSString+FontAwesome.h"
#implementation overlayView
- (instancetype)initWithTitle:(NSString *)title dateFrom:(NSString *)dateFrom dateTo:(NSString *)dateTo description:(NSString *)description {
self.overlayViewTitleLbl.text = title;
self.overlayViewDateFromLbl.text = dateFrom;
self.overlayViewDateToLbl.text = dateTo;
self.overlayViewDescLbl.text = description;
self.overlayViewIcon.text = [NSString fontAwesomeIconStringForIconIdentifier:#"fa-calendar"];
return self;
}
-(void)showOverlay {
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
[window addSubview:self]; <-- Code causing issue
[window makeKeyAndVisible];
}
-(void)dismissOverlay {
// Not wired in yet
}
#end
The being called in my main view controller like:
overlay = [[overlayView alloc] initWithTitle:[tmpDict objectForKeyedSubscript:#"Title"] dateFrom:startDate dateTo:stopDate description:[tmpDict objectForKeyedSubscript:#"Desc"]];
[overlay showOverlay];
Any ideas why this doesn't want to play ball? I have breakpointed the initWithTitle method and all information is being passed correctly so I think I am very close to what I am trying to achieve.
you need to initiate your view first, you're returning self without initiating it
- (instancetype)initWithTitle:(NSString *)title dateFrom:(NSString *)dateFrom dateTo:(NSString *)dateTo description:(NSString *)description {
self = [super init];
if (self) {
self.overlayViewTitleLbl.text = title;
self.overlayViewDateFromLbl.text = dateFrom;
self.overlayViewDateToLbl.text = dateTo;
self.overlayViewDescLbl.text = description;
self.overlayViewIcon.text = [NSString fontAwesomeIconStringForIconIdentifier:#"fa-calendar"];
}
return self;
}

Plist Data not loading in a different iOS Simulator Device

UPDATE Just resetted al Simulators Data and now it works fine.
I'll appreciate any help :)
My app writes data to a Data.plist file in a subfolder of Documents.
I added an NSLog to find out the path so I can check it. I finded and the plist is good.
I tried it in a iPad Air. Another page has a "Load" button for loading the plist data and placing it in a textfield. In the iPad Air the info is loaded totally fine.
BUT! I tried it in an iPad 2. And the 2 strings are not loaded. The keys and objects are:
proyectName string example
revisarCimiento bool 1
tipoCodigoEsfuerzosAdmisibles string Canada
tipoUnidadMamposteria string Block
mamposteriaConfinada bool 0
When the data is loaded, the proyect name doesn't depend on the plist.
The bools are fine but the other 2 strings are not loaded.
Here is the code
.h
//
// factoresCombinacionesCargaViewController.h
// calcMurosLosas
//
// Created by Brian Matus on 15/12/14.
// Copyright (c) 2014 Matus. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface factoresCombinacionesCargaViewController : UIViewController <UITextFieldDelegate>
- (IBAction)loadData:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *proyectName;
#property (weak, nonatomic) IBOutlet UITextField *levels;
#property (weak, nonatomic) IBOutlet UITextField *revisarCimiento;
#property (weak, nonatomic) IBOutlet UITextField *tipoCodigoEsfuerzosAdmisibles;
#property (weak, nonatomic) IBOutlet UITextField *tipoUnidadMamposteria;
#property (weak, nonatomic) IBOutlet UITextField *mamposteriaConfinada;
+ (void)proyectPath:(NSString *)theString;
#end
.m
#import "factoresCombinacionesCargaViewController.h"
#import "infoGeneralViewController.h"
#interface factoresCombinacionesCargaViewController ()
#end
NSString *proyectPath;
#implementation factoresCombinacionesCargaViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
- (IBAction)loadData:(id)sender {
[infoGeneralViewController getProyectNameFromPlist]; //This calls a method that returns a string tho the proyectPath method below.
[self performSelector:#selector(setLabels) withObject:nil afterDelay:0.1];
}
+ (void)proyectPath:(NSString *)theString {
proyectPath = theString;
}
-(void)setLabels {
NSMutableDictionary *plist = [NSMutableDictionary dictionaryWithContentsOfFile:[proyectPath stringByAppendingPathComponent:#"Data.plist"]];
_proyectName.text = [proyectPath lastPathComponent];
int leves = [[plist objectForKey:#"numeroNiveles"] integerValue];
_levels.text = [NSString stringWithFormat:#"%d", leves];
bool revisarCimiento = [[plist objectForKey:#"revisarCimiento"] boolValue];
_revisarCimiento.text = [NSString stringWithFormat:#"%s", revisarCimiento ? "Si" : "No"];
_tipoCodigoEsfuerzosAdmisibles.text = [plist objectForKey:#"tipoCodigoEsfuerzosAdmisibles"];
_tipoUnidadMamposteria.text = [plist objectForKey:#"tipoUnidadMamposteria"];
bool mamposteriaConfinada = [[plist objectForKey:#"mamposteriaConfinada"]boolValue];
_mamposteriaConfinada.text = [NSString stringWithFormat:#"%s", mamposteriaConfinada ? "Si" : "No"];
}
#end
I don't why in the iPad Air the strings are loaded fine but in the iPad 2 not.
Thanks for your attention.

iOS problems sharing data between view controllers

I'm having problems passing data between two view controllers.
I've seen two ways to do this.
One involves implementing prepareForSeque: in the segue's source view controller and another involves setting properties in the viewDidLoad: method of the segue's destination view controller.
e.g.-
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"toEmailReservationViewController"]) {
FLSendEmailViewController *controller = (FLSendEmailViewController *)segue.destinationViewController;
if (!controller.startDateField.text) {
controller.startDateField.text = #"today";
}
}
}
and
- (void)viewDidLoad
{
[super viewDidLoad];
self.startDateField.text = ((FLViewController *)self.presentingViewController).startDate;
}
I've got these to work on simple apps using two UIViewController. However, I can't get them to work on an app that has a UITabViewController connected to some UINavigationViewController connected to custom subclasses of UIViewController. When I click the button to perform the push seque, I get to the view I want, but the startDateField.text doesn't have the text from the segue's source view controller.
Why are these methods of sharing data not working with the tab controller and navigation controller setup?
I noticed that in prepareForSegue: I can't set controller.startDateField.text; as shown when I try to set it and use NSLog to display it. Could this be the problem? Is it possible that the property controller.startDateField.text doesn't exist yet?
I'm trying to grab the date from a datePicker in an instance of FLViewController, store this date in the property NSString *startDate, and in an instance of FLSendEmailViewController set NSString *startDateField.text to the `NSString *startDate'.
Here are the UIViewController subclasses I created:
FLViewController.h
#import <UIKit/UIKit.h>
#import "FLSendEmailViewController.h"
// import frameworks to use ad
#import AddressBook;
#import AddressBookUI;
#interface FLViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIScrollView *theScroller;
#property (weak, nonatomic) NSString *startDate;
#property (weak, nonatomic) NSString *stopDate;
- (IBAction)exitToReservations:(UIStoryboardSegue *)sender;
#end
FLViewController.m
#import "FLViewController.h"
#interface FLViewController ()
#property (weak, nonatomic) IBOutlet UIDatePicker *startReservationDatePicker;
#property (weak, nonatomic) IBOutlet UIDatePicker *stopReservationDatePicker;
#end
#implementation FLViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.theScroller setScrollEnabled:YES];
[self.theScroller setContentSize:CGSizeMake(280, 1000)];
//setup reservationDatePicker
[self.startReservationDatePicker addTarget:self
action:#selector(startDatePickerChanged:)
forControlEvents:UIControlEventValueChanged];
[self.stopReservationDatePicker addTarget:self
action:#selector(stopDatePickerChanged:)
forControlEvents:UIControlEventValueChanged];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// add method called when user changes start date
- (void)startDatePickerChanged:(UIDatePicker *)datePicker
{
NSDateFormatter *dateFortmatter = [[NSDateFormatter alloc] init];
[dateFortmatter setDateFormat:#"dd--MM-yyyy HH:mm"];
// get date using stringFromData: method and getter datePicker.date
self.startDate = [dateFortmatter stringFromDate:datePicker.date];
NSLog(#"The start date is %#", self.startDate);
}
// add method called when user changes stop date
- (void)stopDatePickerChanged:(UIDatePicker *)datePicker
{
NSDateFormatter *dateFortmatter = [[NSDateFormatter alloc] init];
[dateFortmatter setDateFormat:#"dd--MM-yyyy HH:mm"];
// get date using stringFromData: method and getter datePicker.date
self.stopDate= [dateFortmatter stringFromDate:datePicker.date];
NSLog(#"The stop date is %#", self.stopDate);
}
- (IBAction)exitToReservations:(UIStoryboardSegue *)sender {
// execute this code upon unwinding
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"toEmailReservationViewController"]) {
FLSendEmailViewController *controller = (FLSendEmailViewController *)segue.destinationViewController;
if (!controller.startDateField.text) {
controller.startDateField.text = #"today";
NSLog(#"in vc startDate is null but set to %#",controller.startDateField.text );
}
}
}
#end
FLSendEmailViewController.h
#import <UIKit/UIKit.h>
#class FLViewController;
#interface FLSendEmailViewController : UIViewController
#property (retain, nonatomic) IBOutlet UITextField *startDateField;
#property (retain, nonatomic) IBOutlet UITextField *stopDateField;
#end
FLSendEmailViewController.m
#import "FLSendEmailViewController.h"
#import "FLViewController.h"
#interface FLSendEmailViewController ()
- (IBAction)sendEmail:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *numberOfDoggies;
#property (weak, nonatomic) IBOutlet UITextField *emailAddressField;
- (IBAction)hideKeyboard:(id)sender;
#end
#implementation FLSendEmailViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.startDateField.text = ((FLViewController *)self.presentingViewController).startDate;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)sendEmail:(id)sender {
NSString *emailString = [NSString stringWithFormat:#"I would like you to watch my %# doggies from %# to %#. Thank you.", self.numberOfDoggies.text, self.startDateField.text, self.stopDateField.text];
NSLog(#"%#",emailString);
}
- (IBAction)hideKeyboard:(id)sender {
[self.startDateField resignFirstResponder];
}
#end
Import the FLSendEmailViewController.h to the "InitialViewController.h"
Add this property to the FLSendEmailViewController.h
#property (nonatomic, strong) NSString *exportedData;
Add this to the FLSendEmailViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.startDateField.text = self.exportedData
}
4.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"toEmailReservationViewController"]) {
FLSendEmailViewController *controller = (FLSendEmailViewController *)segue.destinationViewController;
if (!controller.startDateField.text) {
controller.exportedData = #"today";
}
}
}
This "sharing method" works in any case when from a controller go to another controller.
So, in case of a navigation controller, if you want push another viewController passing the data, you have just to set the trigger in the Storyboard (if you are using storyboard) from the button, and the new viewController.
So, you will not met troubles. Otherwise, you are committing other type of errors, and in this case, update your question.

Simple math app: answer always equals 1

I'm new to programming so this is probably a result of my illiteracy, but I would appreciate a solution anyways.
I'm trying to make an app that takes the user input from 12 different textfields and feeds out an answer into a label by mathematically altering the user input using Cramer's rule.
So far, I've been trying to multiply the user input from one textfield by the user input from another and feed it out into a label, but whenever I type in my numbers, the product is always 1, and it doesn't print to the label.
Here is my code:
//
// ViewController.h
// Cramer
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
// Objects are given addresses:
#property (weak, nonatomic) IBOutlet UITextField *box_a;
#property (weak, nonatomic) IBOutlet UITextField *box_b;
#property (weak, nonatomic) IBOutlet UILabel *hiLabel;
#property (weak, nonatomic) IBOutlet UIButton *clickButton;
#end
AND
//
// ViewController.m
// Cramer
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// Math takes place:
- (IBAction)clickButton:(id)sender {
NSInteger number1 = [self.box_a.text integerValue];
NSInteger number2 = [self.box_b.text integerValue];
NSInteger prod = number1 * number2;
self.hiLabel.text = [NSString stringWithFormat:#"%#", #(prod)];
}
#end
Thanks
Use %ld as the format specifier in the last statement:
self.hiLabel.text = [NSString stringWithFormat:#"%ld", prod];

Issue Passing Values From One View Controller To Another

I am trying to take the text that is typed into UITextFields in one view, and pass those values into a different View Controller when a button is pressed. In the first view controller (CreateViewController) I have:
#import <UIKit/UIKit.h>
#import <MessageUI/MFMailComposeViewController.h>
#class ThePreviewViewController;
#interface CreateViewController : UIViewController <UIAlertViewDelegate, MFMailComposeViewControllerDelegate> {
UIDatePicker *datePicker;
UIDatePicker *datePicker2;
ThePreviewViewController *_thePreview;
}
#property (nonatomic, retain) IBOutlet UITextField *toName;
#property (nonatomic, retain) IBOutlet UITextField *fromName;
#property (nonatomic, retain) IBOutlet UITextField *issue;
#property (nonatomic, retain) ThePreviewViewController *thePreview;
#property (nonatomic, retain) IBOutlet UITextField *expire;
#property (nonatomic, retain) IBOutlet UITextField *loveMessage;
#property (nonatomic, retain) IBOutlet UITextField *gift;
-(IBAction)build;
#end
The implementation file is:
#import "ThePreviewViewController.h"
#implementation CreateViewController
#synthesize toName, fromName, gift, loveMessage, issue, expire, datePicker, datePicker2;
#synthesize thePreview = _thePreview;
-(IBAction)preview {
if (_thePreview == nil) {
self.thePreview = [[ThePreviewViewController alloc] initWithNibName:#"ThePreviewViewController" bundle:[NSBundle mainBundle]] ;
}
_thePreview.issue.text = issue.text;
_thePreview.gift.text = gift.text;
_thePreview.expire.text = expire.text;
[self.navigationController pushViewController:_thePreview animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
However, after I connect all the outlets, the labels in ThePreviewViewController stay at null. Thoughts?
It looks like this is due to an issue which has been discussed here before: when you instantiate your ThePreviewViewController its UIKit instances are not yet available to have their properties set.
The solution is to create and set NSString properties on your ThePreviewViewController (or more compactly use an NSDictionary) which then use, in its ViewWillAppear event handler to set the properties of its UIKit elements.
Instead of setting UITextField text in ThePreview VC, you should set a NSString property. This is because the UITextField might not have been loaded yet and _thePreview.issue.text = issue.text, will have no effect, since _thePreview.issue has still not been created. So create a property (eg. NSString *issueString) in your ThePreview VC and then set that property as _thePreview.issueString = issue.text in your CreateViewController, and then finally in your ThePreview VC set your textField text in your viewDidLoad method using self.issue.text = self.issueString;
Hope this helps.

Resources