Swapping with NSViewController - objective-c

I am trying swapping two Views in a Windows. I am using Cocoa Framework (just for Mac) with Xcode 5.1.1 and NSViewController for get it. All compile perfectly but this doesn't works,
I get the next message from compiler:
"libdyld.dylib 0x00007fff866995fd start + 1"
This is my Xcode Project
.h file
#import "Cocoa/Cocoa.h"
#import "PrimaryViewController.h" //My views
#import "SecondViewController.h"
#interface
AppDelegate : NSObject <NSApplicationDelegate>
#property (assign) IBOutlet NSWindow *window;
#property (weak) IBOutlet NSView *myCustomView;
#property (strong) IBOutlet NSViewController *myViewController;
-(IBAction)button1Clicked:(id)sender;
-(IBAction)button2Clicked:(id)sender;
#end
.m
#import "AppDelegate.h"
#implementation AppDelegate
//#synthesize myCustomView = _myCustomView;<br/>
//#synthesize myViewController = _myViewController;<br/>
-(IBAction)button1Clicked:(id)sender {
NSLog(#"Clicked on the first button");
[[_myViewController view ]removeFromSuperview];
_myViewController = [[PrimaryViewController alloc] initWithNibName:#"PrimaryView­Controller" bundle:nil];
[_myCustomView addSubview:[_myViewController view]];
[[_myViewController view] setFrame:[_myCustomView bounds]];
}
-(IBAction)button2Clicked:(id)sender {
NSLog(#"Clicked on the second button");
[[_myViewController view] removeFromSuperview];
_myViewController = [[SecondViewController alloc]initWithNibName:#"SecondaryView­Controller" bundle:nil];
[_myCustomView addSubview:[_myViewController view]];
[[_myViewController view]setFrame:[_myCustomView bounds]];
}
#end
Can you help me, please?

In SecondaryViewController.xib you named the file owner as SecondViewController. Change it to SecondaryViewController and it should work.

O yeah, when i created my second "view" i created a file: SecondViewController.xib, SecondViewController.h, and SecondViewController.m
So when i created a instance of it, into the method "button2Clicked" in the, initWithNibName
I called it #"SecondaryViewController" (vs #"SecondViewController").
I removed SecondaryViewController and i changed it, for SecondViewController and all works perfectly, thanks #TheAmateurProgrammerless ;)
Here my project fix it

Related

EXEC_BAD_ACCESS when clicking on a button in objective C

I am just learning and trying to put forth some of the knowledge with objective c and cocoa. I have a little program that has a login screen which then displays a main menu. On the main menu view, there is a button that should load a view to be able to add some data to the app. When I click on the button, it doesn't fire the IBAction but throws an error
EXC_BAD_ACCESS [StartMenuViewController performSelector:withObject:]: message sent to deallocated instance 0x6080195e9f90
I know that it is because there is an object that is not instantiated when the message is being sent, but I cannot find out why. Sorry for the code and the novice level here is the main menu view controller StartMenuViewController.m file:
#import "StartMenuViewController.h"
#import "AppDelegate.h"
#import "MasterViewController.h"
#interface StartMenuViewController ()
#end
#implementation StartMenuViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do view setup here.
}
-(IBAction)showStrainView:(id)sender{
AppDelegate *delegate = nil;
delegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
MasterViewController *addStrainView = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
[delegate swapView:self.view toView:addStrainView.view];
}
#end
here is the StartMenuViewController.h
#import <Cocoa/Cocoa.h>
#interface StartMenuViewController : NSViewController
#property (weak) IBOutlet NSButton *showStrainViewButton;
#end
Here is the AppDelegate.h
#import <Cocoa/Cocoa.h>
#class loginView, MasterViewController,StartMenuViewController;
#interface AppDelegate : NSObject <NSApplicationDelegate>{
loginView *loginView;
MasterViewController *masterViewController;
}
#property (assign) IBOutlet NSWindow *window;
#property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
#property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
#property (strong) loginView *loginView;
#property (strong) MasterViewController *masterViewController;
#property (strong) StartMenuViewController *starMenuViewController;
-(void)swapView:(NSView *)view1 toView:(NSView *)view2;
#end
Here is the AppDelegate.m
#import "AppDelegate.h"
#include "MasterViewController.h"
#import "ScaryBugDoc.h"
#import "Strains.h"
#import "loginView.h"
#interface AppDelegate()
#end
#implementation AppDelegate
#synthesize managedObjectContext = _managedObjectContext;
#synthesize managedObjectModel = _managedObjectModel;
#synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
#synthesize loginView;
#synthesize masterViewController;
#synthesize starMenuViewController;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// 1. Create the master View Controller
self.loginView = [[loginView alloc] initWithNibName:#"loginView" bundle:nil];
// 2. Add the view controller to the Window's content view
[self.window.contentView addSubview:self.loginView.view];
self.loginView.view.frame = ((NSView*)self.window.contentView).bounds;
}
-(void)swapView:(NSView *)view1 toView:(NSView *)view2{
//[view1 removeFromSuperview];
[self.window.contentView addSubview:view2];
view2.frame = ((NSView*)self.window.contentView).bounds;
}
#end
If you need the loginView.h and loginView.m files I can add them as well. I would appreciate any and all help. Thanks in advance
The problem is here:
MasterViewController *addStrainView = [[MasterViewController alloc]initWithNibName:#"MasterViewController" bundle:nil];
[delegate swapView:self.view toView:addStrainView.view];
You don't keep a reference to the MasterViewController so it gets deallocated even though its view is kept around. Now anytime the view tries to access methods from the view controller, things fail.
You should make addStrainView a child view controller of self in the above code so the view controller sticks around as long as its view.

NSScrollView in NSViewController

I am making my first OSX app. My appDelegate has a window which has a contentView of NSViewController. This NSViewController has a custom view which displays on startup. I added an NSScrollView as a property of my NSViewController, and in the xib I put it in the correct position and referenced it to the files owner (the NSViewController). The scrollView never displays when the view is displayed. The code that includes the scrollView is as follows:
in the .h for the viewController:
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#import "StockData.h"
#interface MasterViewController : NSViewController {
IBOutlet NSScrollView * scrollView1;
}
#property (retain) IBOutlet NSScrollView * scrollView1;
#property (retain) NSView * contents;
#end
in the .m for the viewController:
#import "MasterViewController.h"
#import <math.h>
#import <Foundation/Foundation.h>
#implementation MasterViewController
#synthesize scrollView1, contents;
- (void) awakeFromNib
{
self.scrollView1 = [[NSScrollView alloc] init];
self.contents = [[NSView alloc] initWithFrame:NSMakeRect(0,0,430,1000)];
[self.view addSubview:scrollView1];
[self.scrollView1 setDocumentView:self.contents];
}
#end
If anyone could help that would be awesome! Thanks!
If I understand your issue, you don't need to alloc/init the scrollView1 if it is well-connected to the xib file. The xib allocates it for your since the scrollView1 is an object of that xib. If you NSLog(#"%#",[scrollView1 description]) before and after your allocation, It should give you two different objects. I would try :
self.contents = [[NSView alloc] initWithFrame:NSMakeRect(0,0,430,1000)];
[self.view addSubview:scrollView1];
[self.scrollView1 setDocumentView:self.contents];
Now you're adding the xib scrollView1 object to the self.view.
Hope it helps!

access to property of another class

How can I access to ViewController property from another class ?
(the ViewController was created by XCode)
this is code of ViewController.h:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#interface ViewController : UIViewController{
AppDelegate *appDelegate; //il delegate disponibile per tutta la classe
int numPag; //indice array (sulle pagine html da visualizzare)
NSString *path;
NSURL *baseURL;
NSString *file;
NSString *contentFile;
}
- (IBAction)sottrai:(id)sender;
- (IBAction)aggiungi:(id)sender;
#property (strong, nonatomic) IBOutlet UILabel *valore;
#property (strong, nonatomic) IBOutlet UIWebView *web;
#end
thanks!
[EDIT]
I use Xcode 4.3.2 and the code of AppDelegate.m not find something like:
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
Now, I put in the method didFinishLaunchingWithOptions:(into AppDelegate.m) this code:
viewController = [[UIViewController alloc] initWithNibName:#"ViewController" bundle:nil];
[viewController.web loadHTMLString:contentFile baseURL:baseURL];
adding in the file AppDelegate.h the variable viewController:
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>{
NSArray *pageInItalian;
NSArray *pageInEnglish;
UIViewController *viewController;
}
#property (strong, nonatomic) NSArray *pageInLanguage;
#property (strong, nonatomic) UIWindow *window;
#end
I did it correctly? the error is: Property 'web' not found on object of type 'UIViewController *'
I think this post might answer your question
How can I access variables from another class?
You need to make your variable accessible from foreign classes (with #property and #synthesize) and then your foreign class need to know your instance of ViewController
[EDIT]
In your AppDelegate.m, there must be a line like this one :
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
This is where your ViewController is instantiate. From there, you can access every property of your ViewController.
[EDIT]
You need to add the following at the beginning of your implementation
#implementation ViewController
#synthesize web;

How do we disable this button with no compiler error?

I am trying to improve myself in Objective-C and what I am on about is now modifying and changing and existed project. I did everything I wanted expect one thing. Theres an info button in my program and it doesnt related with .xib file. I tried to remove it but always my main.m gave error like SIGABRT (int retval thing.)
Here is the thing what I want to modify
http://i.stack.imgur.com/ZG51s.png // The picture of my program and info button
I am trying to remove the (i) button on the right-down corner.
Here's my code
This is my RootViewController.h
#import <UIKit/UIKit.h>
#class MainViewController;
#interface RootViewController : UIViewController {
IBOutlet UIButton *infoButton; //Silinecek
MainViewController *mainViewController;
}
#property (nonatomic, retain) MainViewController *mainViewController;
#end
This is my RootViewController.m
#import "RootViewController.h"
#import "MainViewController.h"
#implementation RootViewController
#synthesize mainViewController;
- (void)viewDidLoad {
MainViewController *viewController = [[MainViewController alloc] initWithNibName:#"MainView" bundle:nil];
self.mainViewController = viewController;
[viewController release];
[self.view insertSubview:mainViewController.view belowSubview:infoButton];
}
and also I tried to modify my AppDelegate h and m. Here they are ;
#import <UIKit/UIKit.h>
#class RootViewController;
#interface AppDelegate : NSObject <UIApplicationDelegate> {
IBOutlet UIWindow *window;
IBOutlet RootViewController *rootViewController;
}
#property (nonatomic, retain) UIWindow *window;
#property (nonatomic, retain) RootViewController *rootViewController;
#end
#import "AppDelegate.h"
#import "RootViewController.h"
#implementation AppDelegate
#synthesize window;
#synthesize rootViewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:[rootViewController view]];
//[window makeKeyAndVisible];
}
/*
- (void)dealloc {
[rootViewController release];
[window release];
[super dealloc];
}
*/
What should I do for removing that info button in my View. Thanks for the any tips
And if you are interested in this is the whole algorithm : http://pastebin.com/hHQkQYS6
Do you still have the control linked somewhere in your xib file? It is declared as an IBOutlet control. Usually when I have these controls I will use the GUI link this control in some way (I can't remember what exactly as I have not done Obj-C in a long time). But I would definitely have a look around you xib file (as well as removing [self.view insertSubview:mainViewController.view belowSubview:infoButton];
The exception mentions:
[<RootViewController 0x4b9ab20> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key infoButton.
The call stack shows that it is thrown by UINib. So this is happening during nib load. So check for all objects present, carefully, in the nib and remove the info button

Objective-C: Calling class 2 instance from class1 [alloc init] way is not working

I've got the following method on a GameScreen.m file, with its own declaration - (void) drawNumbers on a GameScreen.h file:
//GameScreen.h
#import <UIKit/UIKit.h>
#interface GameScreen : UIView
{
IBOutlet UIButton *cell00;
}
- (void) drawNumbers;
- (IBAction) onCellClick:(id)sender;
#property (nonatomic, retain) IBOutlet UIButton *cell00;
#end
//GameScreen.m
#import "GameScreen.h"
- (void) drawNumbers
{
//testing if this works, so far it doesn't
[cell00 setTitle:#"Whatever" forState:UIControlStateNormal];
[cell00 setTitle:#"Whatever" forState:UIControlStateHighlighted];
}
I'm trying to call this method from my GameScreenViewController.m file, this way:
//GameScreenViewController.m
#import "GameScreenViewController.h"
#import "GameScreen.h"
...
- (void) viewDidLoad
{
GameScreen *aGameScreen = [[GameScreen alloc] init];
[aGameScreen drawNumbers];
[aGameScreen release];
[super viewDidLoad];
}
This is supposed to change the title of a button in a GameScreen.xib file where GameScreenViewController.m is the viewController and GameScreen class is the event handler where I get all the button clicks, timers running, etc. I am trying to call [drawNumbers] from [viewDidLoad] since I want the title to be changed when the screen is brought up front (screen management is done through the AppDelegate files).
The thing is, if I call drawNumbers instance from inside the same class through
//GameScreen.m
#import GameScreen.h
-(void) onButtonClick:(id)sender
{
//some other code
[self drawNumbers];
}
it works (as to say, nothing wrong with the code implementation or the graphic interface).
I've browsed through Apple Guide and tons of pages on the Internet, but I can't seem to find any light to this. Any further help (including answers as to where exactly find the answer in the ADG) would be really appreciated.
(Edited: here goes the AppDelegate code to flip to the specific view, just in case):
//myAppAppDelegate.h
#import <UIKit/UIKit.h>
#class myAppViewController, GameScreenViewController;
#interface myAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
myAppViewController *viewController;
GameScreenViewController *gameScreenViewController;
}
- (void) flipToGameScreen;
#property (nonatomic, retain) UIWindow *window;
#property (nonatomic, retain) GameScreenViewController *gameScreenViewController;
#end
//myAppAppDelegate.m
-(void) flipToGameScreen
{
GameScreenViewController *aGameScreenView = [[GameScreenViewController alloc] initWithNibName: #"GameScreen" bundle:nil];
[self setGameScreenViewController:aGameScreenView];
[aGameScreenView release];
[gameScreenViewController.view.frame = [[UIScreen mainScreen] applicationFrame];
[viewController.view removeFromSuperview];
[self.window addSubview:[gameScreenViewController view]];
}
Since your cell00 is to be set by a NIB it will be nil if you simply do [[GameScreen alloc] init]. It will only be set if the corresponding NIB is loaded (and a connection is actually set up).
If the cell can be accessed in your viewDidLoad, create a property on GameScreen and pass it through the property (or a dedicated initWithCell: or something).
If you have something like an IBOutlet GameScreen *aGameScreen; on your GameScreenViewController (and also established a connection to cell00 in the same NIB) you should access that instead.