Orientation Problem with more Views and Controller (iPad) - objective-c

Im writing an App for iPad using Orientation.
The App-Delegate.h has a window, an UIViewController, an UINavigationController and an UITabbarController:
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet LoginRVC *loginRVC;
#property (nonatomic, retain) IBOutlet ChooseCameraRVC *chooseCameraRVC;
#property (nonatomic, retain) IBOutlet UITabBarController *hauptRVC;
Every Controller uses the "shouldAutorotateToInterfaceOrientation"-method to autorotate itself.
i change the views using:
[UIView beginAnimations:nil context:NULL];
and then
[loginRVC.view removeFromSuperview];
[_window addSubview:chooseCameraRVC.view];
and the other way around too, ofc.
So my problem is, when i am in the second view (chooseCameraRVC) and switch the orientation, then go back to my first view, its not rotated. It do autorotate but after the animation is completed.
I tried many things like calling "shouldAutorotateToInterfaceOrientation"-method of all views, not removing the views from window ... but no success til now.
Is this maybe a "feature" of the simulator? (i hope not).
Pls help me.
Sharky
Ok. I prepared my source code to be presented here.
Note: I didn't copy the methods which only has [super ...] within or are completely commented out.
At first the AppDelegate.h:
#import <UIKit/UIKit.h>
#import "ChooseCameraRVC.h"
#import "LoginRVC.h"
#interface NetCoWatchAppDelegate : NSObject <UIApplicationDelegate>
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet LoginRVC *loginRVC;
#property (nonatomic, retain) IBOutlet ChooseCameraRVC *chooseCameraRVC;
-(void)changeView:(id)sender:(BOOL)direction;
#end
AppDelegate.m:
#import "NetCoWatchAppDelegate.h"
#import "LoginRVC.h"
#import "ChooseCameraRVC.h"
#import "ChooseCameraVC.h"
#implementation NetCoWatchAppDelegate
#synthesize window = _window;
#synthesize loginRVC, chooseCameraRVC;
-(void)changeView:(id)sender:(BOOL)direction{
//configure animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2];
if(sender == loginRVC){ //sender is LoginView
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:_window cache:YES];
[loginRVC.view removeFromSuperview];
[_window addSubview:chooseCameraRVC.view];
}else if(sender == chooseCameraRVC){
[chooseCameraRVC.view removeFromSuperview];
if(!direction){ //FlipFromRight = YES, ...left = NO
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:_window cache:YES];
[_window addSubview:loginRVC.view];
}
}else if([sender class] == [ChooseCameraVC class]){
[chooseCameraRVC.view removeFromSuperview];
if(!direction){ //Camera gewählt //FlipFromRight = YES, ...left = NO
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:_window cache:YES];
[_window addSubview:loginRVC.view];
}
}else { //default solution
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Bad Value" message:[[sender class] description] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
[av release];
}
[UIView commitAnimations]; //start animation
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// Add the navigation controller's view to the window and display.
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc
{
[_window release];
[loginRVC release];
[chooseCameraRVC release];
[super dealloc];
}
#end
The LoginRVC.h:
#import <UIKit/UIKit.h>
#interface LoginRVC : UIViewController <UITextFieldDelegate>{
NSMutableArray *usernameArray;
NSMutableArray *passwordArray;
}
#property (nonatomic, retain) IBOutlet UITextField *usernameTF;
#property (nonatomic, retain) IBOutlet UITextField *passwordTF;
#property (nonatomic, retain) IBOutlet UIButton *loginBn;
#property (nonatomic, retain) IBOutlet UISwitch *saveUsernameSwitch;
-(IBAction)tryLogin:(id)sender;
-(IBAction)closeKeyboard:(id)sender;
#end
The LoginRVC.m:
#import "LoginRVC.h"
#import "NetCoWatchAppDelegate.h"
#implementation LoginRVC
#synthesize usernameTF, passwordTF, loginBn, saveUsernameSwitch;
-(IBAction)tryLogin:(id)sender{
//login successful if the textfields are euqal with an existing account
#warning Access the data base and search for the account.
bool accountFound = NO;
for (int i=0; i<usernameArray.count; i++) {
if([[usernameArray objectAtIndex:i] isEqualToString:usernameTF.text]
&& [[passwordArray objectAtIndex:i] isEqualToString:passwordTF.text]){
accountFound = YES;
break;
}
}
if(accountFound)
{ //login successful - now change the values and then the view
if(![saveUsernameSwitch isOn])
usernameTF.text = #"";
passwordTF.text = #"";
NetCoWatchAppDelegate *main = (NetCoWatchAppDelegate*)[[UIApplication sharedApplication] delegate];
[main changeView:self:YES];
}else{ //login failt - show a popup window for the user
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Login fehlgeschlagen" message:#"Username oder Passwort falsch!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
[av release];
}
}
-(IBAction)closeKeyboard:(id)sender{
if([passwordTF isFirstResponder])
[passwordTF resignFirstResponder];
else
[usernameTF resignFirstResponder];
}
// this helps dismiss the keyboard then the "done" button is clicked
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if(textField == usernameTF){ //move to password textfield
[textField resignFirstResponder];
[passwordTF becomeFirstResponder];
}else if(textField == passwordTF){ //textField == passwordTF -> try to login
[textField resignFirstResponder];
[self tryLogin:self];
}
return YES;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.textFieldRounded.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
#warning Define right keyboard type.
usernameArray = [[NSMutableArray alloc] initWithObjects:#"dkoehn", #"bmazanek", #"sbehne", #"mballhausen", #"efiedler", #"bbraasch", #"azuber", #"tstolt", nil];
passwordArray = [[NSMutableArray alloc] initWithObjects:#"test1",#"test2",#"test3",#"test4",#"test5",#"test6",#"test7",#"test8", nil];
// usernameTF.keyboardType = UIKeyboardTypeEmailAddress;
[usernameTF becomeFirstResponder]; //get first focus when the app stars
//set return key on the keyboard and the delegate for an action
usernameTF.returnKeyType = UIReturnKeyNext; // type of the return key
passwordTF.returnKeyType = UIReturnKeyGo;
//set delegate to connect with a method "-(BOOL)textFieldShouldReturn:(UITextField *)textField"
usernameTF.delegate = self;
passwordTF.delegate = self;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#end
The ChooseCameraRVC.h:
#import <UIKit/UIKit.h>
#interface ChooseCameraRVC : UINavigationController <UINavigationControllerDelegate>
#property (nonatomic, retain) IBOutlet UIBarButtonItem *zurueckBN;
-(IBAction)exitToLoginView:(id)sender;
#end
The ChooseCameraRVC.m:
#import "ChooseCameraRVC.h"
#import "NetCoWatchAppDelegate.h"
#import "ChooseCameraCell.h"
#implementation ChooseCameraRVC
#synthesize zurueckBN;
-(IBAction)exitToLoginView:(id)sender{
#warning Eventually logout the User.
//change the view
[((NetCoWatchAppDelegate*)[[UIApplication sharedApplication] delegate]) changeView:self:NO];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#end
ChooseCameraVC.h:
#import <UIKit/UIKit.h>
#interface ChooseCameraVC : UITableViewController <UITableViewDelegate>
#end
and the ChooseCameraVC.m:
#import "ChooseCameraVC.h"
#import "ChooseCameraCell.h"
#import "NetCoWatchAppDelegate.h"
#implementation ChooseCameraVC
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Customize the number of sections if grouped.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
#warning Get count of cameras out of the data base.
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
cell.textLabel.text = #"Camera";
return cell;
}
#end
I hope u can find the problem.
Greetings. $h#rky

now i found my mistake. as u can see i have the views as variables in the app delegate. so if the second view changes the orientation, the other ones didn't know a thing about it. if the view now changes the "new" one recognizes the orientation change AFTER the animation, so while the animation is running, the "new" view has the wrong orientation.
So if u want to switch a view, just create a new one because it gets initialized with the right orientation.
kind regards
$h#rky

For support all orientations your viewcontroller should implement shouldAutorotateToInterfaceOrientation like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
Every viewcontroller should implement this method for support required orientations.
Check also Supported interface orientations item in .plist file. Maybe you have wrong parameters.

Try this in your secondviewcontroller
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
UIViewController *controller = [self.navigationController.viewControllers objectAtIndex:0];
[controller shouldAutorotateToInterfaceOrientation:interfaceOrientation];
return YES;
}
Hope it works..!!:)

Related

Create a UIPageViewController with a UITableView in each page

I have been reading things on stack overflow for quite a while now but this is my first post, only because it is the first time I have a problem that no one else seems to have fixed yet!
Ok, down to business. It should be a simple matter to put UITableViews inside a UIPageView but I am having difficulties. I have a ViewController and contentViewController. I am using .xibs instead of storyboarding. The contentViewController.xib is a Table View and the ViewController.xib is a View. I am only focusing on iPhone. The UITableView is connected to dataSource, delegate, and Referencing Outlet named theTableView.
The project builds but when I run it I get the following error message:
2013-03-17 16:14:23.026 pageApp[775:c07] *** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2380.17/UIView.m:5776
2013-03-17 16:14:23.028 pageApp[775:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'
*** First throw call stack:
(0x1c93012 0x10d0e7e 0x1c92e78 0xb66665 0x6539f 0x10e46b0 0x228ffc0 0x228433c 0x228feaf 0x1042bd 0x4cb56 0x4b66f 0x4b589 0x4a7e4 0x4a61e 0x4b3d9 0x4e2d2 0xf899c 0x45574 0x4576f 0x45905 0x4e917 0x20eb 0x12157 0x12747 0x1394b 0x24cb5 0x25beb 0x17698 0x1beedf9 0x1beead0 0x1c08bf5 0x1c08962 0x1c39bb6 0x1c38f44 0x1c38e1b 0x1317a 0x14ffc 0x1d2d 0x1c55)
libc++abi.dylib: terminate called throwing an exception
This crashes after -(void)viewDidLoad{} in ViewController.m and I have not yet learned how to fix auto layout/ layoutSubview errors. Does anyone else know how?
I have limited experience with ios development so I am sure that I just don't have the right pieces in the right spots. I used http://www.techotopia.com/index.php/An_Example_iOS_5_iPhone_UIPageViewController_Application to get this far.
My code is as follows:
ViewController.h
#import <UIKit/UIKit.h>
#import "contentViewController.h"
#interface ViewController : UIViewController
<UIPageViewControllerDataSource>
{
UIPageViewController *pageController;
NSArray *pageContent;
}
#property (strong, nonatomic) UIPageViewController *pageController;
#property (strong, nonatomic) NSArray *pageContent;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize pageController, pageContent;
- (contentViewController *)viewControllerAtIndex:(NSUInteger)index
{
// Return the data view controller for the given index.
if (([self.pageContent count] == 0) || (index >= [self.pageContent count])) {
return nil;
}
// Create a new view controller and pass suitable data.
contentViewController *dataViewController =[[contentViewController alloc]initWithNibName:#"contentViewController"bundle:nil];
dataViewController.dataObject =[self.pageContent objectAtIndex:index];
return dataViewController;
}
- (NSUInteger)indexOfViewController:(contentViewController *)viewController
{
return [self.pageContent indexOfObject:viewController.dataObject];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:(contentViewController *)viewController];
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = [self indexOfViewController:(contentViewController *)viewController];
if (index == NSNotFound) {
return nil;
}
index++;
if (index == [self.pageContent count]) {
return nil;
}
return [self viewControllerAtIndex:index];
}
- (void) createContentPages
{
NSMutableArray *pageStrings = [[NSMutableArray alloc] init];
for (int i = 1; i < 4; i++)
{
NSString *contentString = [[NSString alloc]initWithFormat:#"Chapter %d \nThis is the page %d of content displayed using UIPageViewController in iOS 5.", i, i];
[pageStrings addObject:contentString];
}
pageContent = [[NSArray alloc] initWithArray:pageStrings];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self createContentPages];
self.pageController = [[UIPageViewController alloc]initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
pageController.dataSource = self;
[[pageController view] setFrame:[[self view] bounds]];
contentViewController *initialViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];
[pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self addChildViewController:pageController];
[[self view] addSubview:[pageController view]];
[pageController didMoveToParentViewController:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
contentViewController.h
#import <UIKit/UIKit.h>
#interface contentViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITableView *theTableView;
#property (strong, nonatomic) id dataObject;
#property (strong, nonatomic) NSArray *pageContent;
#end
contentViewController.m
#import "contentViewController.h"
#interface contentViewController ()
#end
#implementation contentViewController
#synthesize theTableView, dataObject, pageContent;
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void) createContentPages
{
NSMutableArray *pageStrings = [[NSMutableArray alloc] init];
for (int i = 1; i < 4; i++)
{
NSString *contentString = [[NSString alloc]initWithFormat:#"Chapter %d \nThis is the page %d of content displayed using UIPageViewController in iOS 5.", i, i];
[pageStrings addObject:contentString];
}
pageContent = [[NSArray alloc] initWithArray:pageStrings];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self createContentPages];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection (NSInteger)section
{
return 4;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [pageContent objectAtIndex:indexPath.row];
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
So if anyone could straighten me out I would appreciate it.
I was able to solve my own problem, and it seems I was just a bit mixed up.
The comment from rdelmar set me on the right track but I hooked the delegate and data source to the wrong object. I had to connect them to File's Owner in order for it to work.
In addition it seems theTableView was not necessary and when I removed that my code suddenly worked as expected.
If this isn't clear enough for an answer please tell me how I can be more specific. Thank you!

Call method from another view, I think?

I have a simple utility app, with a MainViewController.m & h and a FlipsideViewController.m & h. Within my storyboard I have a button on MainViewController. I want to be able to click the button and run a method in FlipsideViewController.m is this possible? this is my first app and I am a total novice. all comments / suggestion welcome.
enter code here
i have this in my FlipsideViewController.m this is what i want to call when i click the button.
- (void)SaveFPQData
{
NSLog(#"Data Saved");
}
and this is what i have in MainViewController.m
- (IBAction)saveButton:(id)sender
{
}
This is the code I have so far;
MainViewController.h
#import "FlipsideViewController.h"
#import "sqlite3.h"
#import "FPQCheck.h"
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate>
#property (weak, nonatomic) IBOutlet UITextField *nameField;
#property (weak, nonatomic) IBOutlet UITextField *checkField;
#property (weak, nonatomic) IBOutlet UITextField *commentsField;
#property (weak, nonatomic) FlipsideViewController *flipsidecontroller;
- (IBAction)saveButton:(id)sender;
- (IBAction)showHistoryButton:(id)sender;
#end
MainViewController.m
#import "MainViewController.h"
#import "FlipsideViewController.h"
#import "sqlite3.h"
#interface MainViewController ()
#end
#implementation MainViewController
- (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.
}
#pragma mark - Flipside View
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showAlternate"]) {
[[segue destinationViewController] setDelegate:self];
}
}
- (IBAction)saveButton:(id)sender
{
[self.flipsidecontroller SaveFPQData];
//[[NSNotificationCenter defaultCenter] postNotificationName:#"SaveFPQData" object:nil];
}
- (IBAction)showHistoryButton:(id)sender
{
}
#end
FlipSideViewController.h
#import <UIKit/UIKit.h>
#import "FPQCheck.h"
#class FlipsideViewController;
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
#interface FlipsideViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *myTableView;
#property (weak, nonatomic) id <FlipsideViewControllerDelegate> delegate;
-(void)SaveFPQData;
- (IBAction)done:(id)sender;
- (IBAction)deleteEntry:(id)sender;
#end
FlipSideViewController.m
#import "FlipsideViewController.h"
#import "MainViewController.h"
#interface FlipsideViewController ()
{
NSMutableArray *arrayOfCheck;
sqlite3 *fpqDB;
NSString *dbPathString;
}
#end
#implementation FlipsideViewController
- (void)viewDidLoad
{
/*
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(SaveFPQData)
name:#"SaveFPQData"
object:nil];
*/
[super viewDidLoad];
arrayOfCheck = [[NSMutableArray alloc]init];
[self creatOrOpenDB];
[[self myTableView]setDelegate:self];
[[self myTableView]setDataSource:self];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)SaveFPQData
{
NSLog(#"Data Saved");
}
-(void)creatOrOpenDB
{
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES);
NSString *docPath = [path objectAtIndex:0];
dbPathString = [docPath stringByAppendingPathComponent:#"FPQ.db"];
char *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:dbPathString]) {
const char *dbPath = [dbPathString UTF8String];
//create db
if (sqlite3_open(dbPath, &fpqDB)==SQLITE_OK) {
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS FPQ (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, CHECK INTEGER, COMMENTS TEXT)";
sqlite3_exec(fpqDB, sql_stmt, NULL, NULL, &error);
sqlite3_close(fpqDB);
}
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Actions
- (IBAction)done:(id)sender
{
[self.delegate flipsideViewControllerDidFinish:self];}
- (IBAction)deleteEntry:(id)sender {
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrayOfCheck count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
FPQCheck *fpqCheck = [arrayOfCheck objectAtIndex:indexPath.row];
NSString *nameANDcheck = [NSString stringWithFormat:#"%#%d", fpqCheck.name, fpqCheck.check];
cell.textLabel.text = nameANDcheck;
cell.detailTextLabel.text = fpqCheck.comments;
return cell;
}
#end
You have mainly two ways:
add a property (eg. self.flipSideController) to your MainViewController to store a reference to the FlipsideViewController; then call SaveFPQData though it (eg. [self.flipSideController SaveFPQData]; or
use notification center to post a notification from saveButton: that triggers SaveFPQData; this would go like this:
//-- in flipsidecontroller `viewDidLoad`:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(SaveFPQData)
name:#"SaveFPQData"
object:nil];
//-- in saveButton:
[[NSNotificationCenter defaultCenter] postNotificationName:#"SaveFPQData" object:nil];
The second method is the simplest to implement, IMO, and it allows for the loosest coupling, at the expense of some clock cycles.
EDIT:
It is not entirely clear to me what you are trying to do (specifically, I don't understand fully how you can push the button in MainViewController once you FlipsideViewController is displayed; on the other hand, if you do not segue to the FlipsideViewController, then it is not there, so you cannot send a message to it), anyway you could try and initialise your self.flipsideViewController property in prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showAlternate"]) {
UIViewController* controller = [segue destinationViewController];
[controller setDelegate:self];
if ([controller isKindOfClass:[FlipsideViewController class]])
self.flipsideViewController = (id)controller;
}
}
after doing that, your MainViewController will be able to send the saveFPQ message to the FlipsideViewController.
If you mean you would like to send the saveFPQ message before segue-ing to the FlipsideViewController, you should make the saveButton segue to it and the call the saveFPQ method.
What I suspect is you need some kind of "model" object accessible both from the main view and the flipside view controller.
Hope this helps.

Works on iPad Simulator but crashes on iPad

Hi I am trying to develop a new app on the ipad. I am using a spitTableView and adding a ModalPresentationPage to the view. This works perfectly on the xcode iPad sim but crashes on my iPad. just so you know I am using xcode 5BATA and running IOS 5 on my iPad.
here is my code
DetailViewController.h
#import <UIKit/UIKit.h>
#interface DetailViewController : UIViewController <UISplitViewControllerDelegate>{
}
-(IBAction)loadView:(id)sender;
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#property (strong, nonatomic) IBOutlet UIToolbar *toolbar;
#end
DetailViewController.m
#import "DetailViewController.h"
#import "ModalViewController.h"
#import "RootViewController.h"
#interface DetailViewController ()
#property (strong, nonatomic) UIPopoverController *popoverController;
- (void)configureView;
#end
#implementation DetailViewController
#synthesize detailItem = _detailItem;
#synthesize detailDescriptionLabel = _detailDescriptionLabel;
#synthesize toolbar = _toolbar;
#synthesize popoverController = _myPopoverController;
-(IBAction)loadView:(id)sender{
ModalViewController *mvc = [[ModalViewController alloc]initWithNibName:#"modalViewController"bundle:nil];
mvc.modalPresentationStyle = UIModalPresentationPageSheet;
mvc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:mvc animated:YES];
}
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
}
return self;
}
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
if (self.popoverController != nil) {
[self.popoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.detailDescriptionLabel.text = [self.detailItem description];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
self.splitViewController.delegate = self;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#pragma mark - Split view
- (void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController: (UIPopoverController *)pc
{
barButtonItem.title = #"Master";
NSMutableArray *items = [[self.toolbar items] mutableCopy];
[items insertObject:barButtonItem atIndex:0];
[self.toolbar setItems:items animated:YES];
self.popoverController = pc;
}
- (void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
// Called when the view is shown again in the split view, invalidating the button and popover controller.
NSMutableArray *items = [[self.toolbar items] mutableCopy];
[items removeObjectAtIndex:0];
[self.toolbar setItems:items animated:YES];
self.popoverController = nil;
}
#end
Parts not under NDA :-
You are leaking items in both the split view delegate methods.
Are you sure the XIB name is modalViewController? There could a problem of it being case sensitive on the device.

if statement not working

I have an app where there is a timer. It goes from 10 to 0. Using NSTimer. I have said:
.m:
//
// Skin.m
// PopThatPimple
//
// Created by Rohan Kapur on 6/2/11.
// Copyright 2011 UWCSEA. All rights reserved.
//
#import "Skin.h"
#implementation Skin
#synthesize theAudio;
#synthesize label;
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [touches anyObject];
CGPoint point = [myTouch locationInView:pimple];
if ( CGRectContainsPoint(pimple.bounds, point) ) {
[self checkcollision];
}
}
-(void)checkcollision {
pimple.center = CGPointMake(
random() % (unsigned int)theview.bounds.size.width,
random() % (unsigned int)theview.bounds.size.height
);
score.text = [NSString stringWithFormat:#"%d", ([score.text intValue] + 1)];
sad.hidden = NO;
NSURL* popURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"pop" ofType:#"mp3"]];
AudioServicesCreateSystemSoundID((CFURLRef) popURL, &popID);
AudioServicesPlaySystemSound(popID);
}
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
-(void)showActivity{
int currentTime = [time.text intValue];
int newTime = currentTime + -1;
time.text = [NSString stringWithFormat:#"%d", newTime];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
-(void)viewDidLoad {
myTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector (showActivity) userInfo:nil repeats:YES];
[label2 setHidden:YES];
[super viewDidLoad];
}
-(void)void2 {
if ([label3.text isEqualToString:#"0"]) {
[[self view] addSubview:timeup];
score.text = label2.text;
label2.hidden = NO;
}
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
-(void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
-(void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
.h:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#interface Skin : UIViewController {
IBOutlet UIImageView *pimple;
IBOutlet UIImageView *smile;
IBOutlet UIImageView *sad;
AVAudioPlayer *theAudio;
IBOutlet UIView *theview;
SystemSoundID popID;
IBOutlet UIImageView *face;
IBOutlet UIImageView *face2;
IBOutlet UIImageView *face3;
IBOutlet UIImageView *face4;
IBOutlet UIImageView *face5;
IBOutlet UIImageView *face6;
IBOutlet UIImageView *face7;
IBOutlet UIImageView *face8;
IBOutlet UIImageView *face9;
IBOutlet UIImageView *face10;
IBOutlet UIImageView *face11;
IBOutlet UIImageView *face12;
IBOutlet UIImageView *face13;
IBOutlet UIImageView *face14;
IBOutlet UIImageView *face15;
IBOutlet UILabel *label2;
IBOutlet UILabel *score;
IBOutlet UIImageView *skin;
IBOutlet UILabel *time;
NSTimer * myTicker;
IBOutlet UILabel *label3;
IBOutlet UIImageView * timeup;
}
-(IBAction)start;
-(void)void2;
-(void)showActivity;
#property (nonatomic, retain) UILabel *label;
#property (nonatomic, retain)AVAudioPlayer *theAudio;
-(void)checkcollision;
#end
I have not used all of my outlets and ibactions yet. And i have not used avfoundation yet
I have CONNECTED EVERYTHING! I HAVE CHECKEED A THOUSAND TIMES! When it reaches zero nothing happens and the timer just goes to the negatives. WHat am I doing wrong?
There are two major problems here, the first is you're using an assignment operator, not a comparison operator, I'd imagine you have a warning on that.
The second is an == comparison is useless here, the fixed code would be.
if ([label3.text isEqualToString:#"0"])
I'll second (third?) what #BoltClock and #Joshua Weinberg wrote, but add that checking the text displayed in a label is a poor way to determine whether a timer has expired. At some point, somewhere in your program, you're setting the label's text to #"0", so you already know that that condition is true. Likewise with the score... your controller should know what the score is, and it definitely shouldn't be relying on a label to get it.
Don't store data in your view objects. Data should flow from your model through your controller to your view. It only flows in the opposite direction when you're accepting user input.

MySecondViewController won't display correctly

I have programmatically created a second view controller (MySecondViewController) which was all done and hooked up without using the visual object editor.
My problem is that when I run the app, only the original view controller (HelloWorldViewController) comes up; the second view controller does not show up. When I click on the view for HelloWorldViewController, nothing comes up.
Can you tell me what's wrong?
windowBasedAppAppDelegate.h
#import <UIKit/UIKit.h>
//-- Add a forward reference to the HelloWorldViewController class --
#class HelloWorldViewController;
#interface windowBasedAppAppDelegate : NSObject <UIApplicationDelegate> {
//-- create an instance of the view controller--
HelloWorldViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
//--Expose the view controller as a property--
#property (nonatomic, retain) IBOutlet HelloWorldViewController *viewController;
#end
windowBasedAppAppDelegate.m
#import "windowBasedAppAppDelegate.h"
#import "HelloWorldViewController.h"
#import "MySecondViewController.h"
#implementation windowBasedAppAppDelegate
#synthesize window;
#synthesize viewController;
//-- a second view controller object--
MySecondViewController *mySecondViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
//-- add the new view to the current window--
//-- instantiate the second view controller --
mySecondViewController = [[MySecondViewController alloc]
initWithNibName:nil
bundle:nil];
// -- add the view from the second controller --
//[window addSubview:mySecondViewController.view];
[window addSubview:viewController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (void)dealloc
{
[MySecondViewController release];
[viewController release];
[window release];
[super dealloc];
}
#end
MySecondViewController.h
#import <UIKit/UIKit.h>
#interface MySecondViewController : UIViewController {
//-- create two outlets, label and button --
UILabel *label;
UIButton *button;
}
//-- expose the outlets as properties --
#property (nonatomic, retain) UILabel *label;
#property (nonatomic, retain) UIButton *button;
// -- declaring the IBAction ---
- (IBAction) buttonClicked: (id)sender;
#end
MySecondViewController.h
#import "MySecondViewController.h"
#implementation MySecondViewController
#synthesize label, button;
- (IBAction) buttonClicked: (id)sender {
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:#"Action Invoked!" message:#"Button clicked" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
[alert release];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
HelloWorldViewController.h
#import <UIKit/UIKit.h>
#interface HelloWorldViewController : UIViewController {
}
#end
HelloWorldViewController.m
import "HelloWorldViewController.h"
#implementation HelloWorldViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
Added code from MySecondViewController.m
//-- add the views to the view window --
[self.view addSubview:label];
[self.view addSubview:button];
[view exchangeSubviewAtIndex:1 withSubviewAtIndex:0];
self.view = view;
[super viewDidLoad];
Since the view is being initialized and that it has a proper frame, the problem could be this sequence of code,
[window addSubview:mySecondViewController.view];
[window addSubview:viewController.view];
As the viewController's view will have the same frame, it will be added over mySecondViewController's view. So you will have to remove the second line for the view to show up.
You never actually push the new view controller onto the screen.
mySecondViewController = [[MySecondViewController alloc]
initWithNibName:nil
bundle:nil];
// -- add the view from the second controller --
//[window addSubview:mySecondViewController.view];
[window addSubview:viewController.view];
You add viewController.view, (which should be undefined...), but not mySecondViewController.view.
Also, programHasFinishedLaunching may not be the best possible place to push it. If I were you, I'd put a button on the front page that pushes the new view in, it's easier that way.