Change background image of a button programmatically cocoa obj-c - xcode

I am creating NSCollection View (in Cocoa) with many identical buttons in size and appearance, except for their icons (or you could probably call them Background Images).
In my xib file I have the button binded to the Collection View (Model key path: representedObject.foto) and the Array Controller has class of MyButton and Keys: foto.
I created My Button class with NSImage property - is this the right way to do it?
How do I set an Image that I have in my project in AppController.m so that it appears on the button when running my app?
Everything else should be fine, because I have previously create NSCollectionView with Labels and it worked.
MyButton.h
#import <Cocoa/Cocoa.h>
#interface MyButton : NSButton
#property(retain, readwrite) NSImage *foto;
#end
MyButton.m
#import "MyButton.h"
#implementation MyButton
#end
AppController.h
#interface AppController : NSObject {IBOutlet NSArrayController *controller;}
#property (strong) NSMutableArray *modelArray;
#end
AppController.m
#import "AppController.h"
#import "MyButton.h"
#implementation AppController
- (void) awakeFromNib {
MyButton *FirstOne = [[MyButton alloc] init];
//FirstOne.foto = ???
_modelArray = [[NSMutableArray alloc] init];
[controller addObject:FirstOne];}
#end

Where is your image located in your project? If its in an .xcasset file, then you can set the image with:
FirstOne.image = [NSImage imageNamed:#"StatusBarIcon"];
You can learn about storing images in assets here. I would recommend using these assets as it allows you to keep all the images that you may use in your project organised, and it helps reduce the hassle of maintaining images for multiple resolutions.

Related

switching views with NSMenuItem IBAction does not work

In a document based Cocoa App I want to fill a NSBox in the Document.xib with a view,
by selecting the view with a NSMenuItem. However, the box is not updated with the view.
If I insert a button in the Document.xib, which is connected with the same IBAction as the NSMenuItem, the app works in the expected way.
I created the tree files:
- ViewController.h
- ViewController.m
- prettyView.xib
In ViewController.m the XIB File of the view is initialized.
// ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (id)init
{
if(![super initWithNibName:#"prettyView" bundle:nil]){
return nil;
}
[self setTitle:#"Pretty View"];
return self;
}
#end
The Document.h contains outlets for the box and two buttons.
One button fills the box with the view, the other one clears the box.
// Document.h
#import <Cocoa/Cocoa.h>
#class ViewController;
#interface Document : NSDocument
#property (weak) IBOutlet NSBox *contentBox;
- (IBAction)fillBox:(id)sender;
- (IBAction)clearBox:(id)sender;
#property ViewController * myViewController;
#end
In Document.m the view controller is instantiated.
// Document.m
#import "Document.h"
#import "ViewController.h"
#interface Document ()
#end
#implementation Document
- (instancetype)init {
self = [super init];
if (self) {
_myViewController = [ViewController new];
}
return self;
}
The methods for the IBActions are implemented in Document.m too.
- (IBAction)fillBox:(id)sender {
NSLog(#"Fill Box selected from %#", [sender className]);
[self.contentBox setContentView:[self.myViewController view]];
}
- (IBAction)clearBox:(id)sender {
NSLog(#"Clear Box selected");
[self.contentBox setContentView:nil];
}
The method fillBox is connected to one of the both buttons as well as to the NSMenuItem.
Pressing the button, a message is written to the console and the view is shown in the box.
Selecting the NSMenuItem, a message is written too, but the view is not displayed in the box.
The IBActions must not be connected with Document but with First Responder of MainMenu.xib.

How do you make a UIImageView's image change when a button is pushed? The UIImageView and UIButton are on two different views

I have a UIButton and a UIImageView. The UIButton and UIImageView are on different views in storyboard. What I want to happen is when the button is pressed, it switches views and the UIImageView switches to a different image. Right now, the view changes, but the UIImageView doesn't change.
Here is the ViewController.h file
#import <UIKit/UIKit.h>
#import "Player.h"
#import "Space.h"
#interface ViewController : UIViewController
{
IBOutlet UIImageView* space0_0;
Player* m_player;
Space* m_spaces[16][16];
}
-(IBAction)startGame;
#end
The reason there is an array of spaces is that I want there to eventually be a 16x16 board of UIImageViews. Right now I only have 1 image view just to get the first one working before moving on
Here is the IBAction connected to the button that is supposed to change the UIImageView
-(IBAction)startGame
{
[m_spaces[0][0] setImageView:space0_0];
[m_spaces[0][0] displaySpace];
}
I made a class called Space. Here is the Space.h file
#import <Foundation/Foundation.h>
#interface Space : NSObject
{
UIImageView* m_imageView;
}
-(void)setImageView:(UIImageView*)imageView;
-(UIImageView*)imageView;
-(void)displaySpace;
#end
Here is the Space.m file
#import "Space.h"
#implementation Space
-(void)setImageView:(UIImageView*)imageView
{
m_imageView = imageView;
}
-(UIImageView*)imageView
{
return m_imageView;
}
-(void)displaySpace
{
m_imageView.image = [UIImage imageNamed:#"player.png"];
}
#end
Can anyone tell me where I'm going wrong here? The only problem is that the UIImageView's image does not change.
Edit: when I change the startGame method to:
-(IBAction)startGame;
{
space0_0.image = [UIImage imageNamed:#"player.png"];
}
So the problem is somewhere in my Space class.

NSWindowController's window released immediately

I'm trying to open a window using a NSWindowController in my app delegate.
I created a basic NSWindowController with an associated NIB and try to show the window that way:
#implementation MyAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Show the main window from a separate nib
MyWindowController * theWindowController = [[MyWindowController alloc] initWithWindowNibName:#"MyWindowController"];
[theWindowController showWindow:self];
}
#end
When I launch the app, the window of MyWindowController only appears for a fraction of second (seems to be released as soon as it launches).
Using ARC, how could I force the window to stick around and not be flushed right away? I do not use NSDocuments and I want to be able to use many of these MyWindowController concurrently.
You need to add a property to your app delegate (or some other object that's going to stick around for the lifetime of your app) that retains theWindowConroller. For example:
#interface MyAppDelegate : NSObject
#property (strong, nonatomic) MyWindowController * windowController;
#end
Then set this property when you initialize the window controller.
#implementation MyAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Show the main window from a separate nib
self.windowController = [[MyWindowController alloc] initWithWindowNibName:#"MyWindowController"];
[theWindowController showWindow:self];
}
#end

Creating a UITabBarController using a NIB outside of AppDelegate?

Still new to iOS programming, and despite copious amounts of research, I have run in to another roadblock.
What I want to implement:
I want a UITabBarController that gets loaded when I navigate from the main UI. I would also like to use a NIB to define its properties.
All of the examples I can find put the UITabBarController in the AppDelegate, but I would not like to load it unless it gets used. I also dont know if all of the UIGestureRecognizers would remain active if I just did it modally (I cant get a working implementation).
What I have so far
First, I load an initial loading view from AppDelegate
AppDelegate.h
#class InitialViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) UIViewController *viewController;
#end
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[InitialViewController alloc] initWithNibName:#"InitialViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
From this view, as I am just making a skeleton of the UI, I have two buttons, one goes to what would be the main interface, and the other to the UITabBarController.
InitialViewController.h
#interface InitialViewController : UIViewController
- (IBAction)toMain:(id)sender;
- (IBAction)toTabs:(id)sender;
#property (strong, nonatomic) UIViewController *mviewController;
#property (strong, nonatomic) UIViewController *tviewController;
#end
InitialViewController.m
- (IBAction)toMain:(id)sender {
self.mviewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
[[[UIApplication sharedApplication] delegate] window].rootViewController = self.mviewController;
}
- (IBAction)toTabs:(id)sender {
self.tviewController = [[tabViewController alloc] initWithNibName:#"tabViewController" bundle:nil];
[[[UIApplication sharedApplication] delegate] window].rootViewController = self.tviewController;
}
On loading MainViewController, it behaves exactly like I want. But when I load the tab view, I get one long tab at the bottom and a black background. I can add in things in viewdidload, like changing the background color, but no actual tabs or views linked to the tabs in the XIB.
I suspect there is something I am missing in two areas: in the tab .h, and some linking associated with that in interface builder. Or setting a new rootViewController isnt enough.
tabBarController.h
#import <UIKit/UIKit.h>
#interface iPodViewController : UITabBarController <UITabBarControllerDelegate>
#end
If someone can point me in the right direction and/or show me an implementation that works, I would be most grateful.
-- as a note, when I go in to the tabbar.xib, and use the assistant editor, it opens InitialViewController.h --
Unlike other view controllers (e.g. UITableViewController) you should not subclass the UITabViewController. Therefore, unlike you other view controllers, you don't subclass and then make your subclass the owner of the nib, pointing at the view in the nib, with a customised view.
Instead, for whichever class that you want to own your UITabBarController, add a plain, vanilla UITabBarController as an outlet property on this class. (e.g. your app delegate).
Then create a nib file and drag a UITabBarController object into the nib. Set the owner of the nib to be the class that you want to own your tab bar controller (e.g. your app delegate) and connect the outlet you created as a property to the tab bar controller in the nib.
#interface myTabOwningClass
#property (strong, nonatomic) IBOutlet UITabBarController myTabBarControllerOutlet;
Now at the point you want to create and display your tab bar controller, use the following method:
[[NSBundle mainBundle] loadNibNamed:#"MyTabControllerNib" owner:myTabOwningClass options:nil];
This will initialise the property (i.e. myTabBarControllerOutlet in our example) on the owning class and load the tab bar controller from the nib, including all sub view controllers for each tab etc. that you have defined in the nib.

How to make a program load an web image and show it on a Custom View?

Well, I'm learning how to program on a mac, and I'm tired of searching the for answers, can you guys explain me what I did wrong on my program.
First, I dragged 2 buttons on my window (Load Image, and Unload). Then, I dragged a custom view item and here`s what I did with the Test_Loading_ImagesAppDelegate.h:
#import <Cocoa/Cocoa.h>
#interface Test_Loading_ImagesAppDelegate : NSView {
NSWindow *window;
IBOutlet NSView *mypicture;
}
- (IBAction)LoadImage: (id)sender;
- (IBAction)Unload: (id)sender;
#property (assign) IBOutlet NSWindow *window;
#end
After that, I linked up things on Interface Builder normally and made the Test_Loading_ImagesAppDelegate.m:
#import "Test_Loading_ImagesAppDelegate.h"
#implementation Test_Loading_ImagesAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
-(IBAction)LoadImage: (id) sender {
NSURL *myurl;
NSImage *image;
NSData *myurldata;
myurl = [NSURL URLWithString:#"http://....jpg"];
myurldata = [NSData dataWithContentsOfURL:myurl];
image = [NSImage initWithData:myurldata];
[mypicture setImage: image];
}
-(IBAction)Unload: (id) sender {
//Well, still thinking how I'm going to do this, and I would like to make another question: If I dealloc the View or something else the image will disappear?
}
#end
Thanks in advance.
Well, after coming here again I've found this http://www.markj.net/iphone-asynchronous-table-image/ it's for iPhone but can be adapted to OS X easily. Thanks.

Resources