Trying to set the bounds of my table view to be smaller than my screen. I am setting it in my viewDidLoad method but nothing happens when I run. Not sure why it's not working. Am I calling it in the right place??
//OptionsViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.frame = CGRectMake(1,1,29,80);
}
// OptionsViewController.h
#import <UIKit/UIKit.h>
#interface OptionsViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
NSIndexPath *selectedRowIndex;
}
#property (weak, nonatomic) NSIndexPath *selectedRowIndex;
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
Set the frame in viewDidAppear method . It works. You might want to look at the following question and answer for a good explanation :
Unable to set frame correctly before viewDidAppear
TL;DR - The UI elements are not drawn to screen yet during viewDidLoad .
Related
I made some example that changes view by clicking button.
When clicking the "fist" button in view, I keep getting the error:
[__NSArrayM changeLogView:]: unrecognized selector sent to instance 0x100539e30
Here is the simplified code:
DSWAppDelegate.h
#import <Cocoa/Cocoa.h>
#class DSWHomeViewController;
#interface DSWAppDelegate : NSObject <NSApplicationDelegate>
#property (assign) IBOutlet NSWindow *window;
#property (weak) IBOutlet NSButton *logBtn;
#property (weak) IBOutlet NSTabView *tabView;
#end
DSWAppDelegate.m
#import "DSWAppDelegate.h"
#import "DSWLogViewController.h"
#implementation DSWAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
[self.tabView setTabViewType:NSNoTabsNoBorder];
NSTabViewItem *item = nil;
DSWLogViewController *logvc = [[DSWLogViewController alloc initWithNibName:#"DSWLogViewController" bundle:[NSBundle mainBundle]];
item = [[NSTabViewItem alloc] initWithIdentifier:#"log"];
[item setView:logvc.view];
[self.tabView insertTabViewItem:item atIndex:0];
}
#end
DSWLogViewController.h
#import <Cocoa/Cocoa.h>
#interface DSWLogViewController : NSViewController
#property (weak) IBOutlet NSButton *firstBtn;
#property (weak) IBOutlet NSButton *secondBtn;
#property (weak) IBOutlet NSBox *box;
- (IBAction)changeLogView:(id)sender;
- (IBAction)testSelector:(id)sender;
#end
DSWLogViewController.m
#import "DSWLogViewController.h"
#implementation DSWLogViewController
- (IBAction)changeLogView:(id)sender
{
NSLog(#"changeLogView : %#", sender);
}
- (IBAction)testSelector:(id)sender
{
NSLog(#"testSelector : %#", sender);
}
#end
And I checked class name of file owner.
Something is sending a changeLogView: message to a mutable array instead of your view controller. Chances are, whatever you've connected the IBAction to is pointing to the wrong object - an array of some sort, rather than your view controller.
I am having several IBOutlets of UIView; several subviews within my parent view.
I am trying to loop over all the subviews which are UIView.
I want to loop over all subviews that have the name of their IBOutlet starting with "view_"
Can somebody help me with this?
Question is I really want to access the name of the IBOutlet.
Here's my code for clarification:
#property (weak, nonatomic) IBOutlet UIView *view_player1;
#property (weak, nonatomic) IBOutlet UIView *view_player2;
#property (weak, nonatomic) IBOutlet UIView *view_referee1;
- (void)listSubviewsOfView:(UIView *)view {
// Get the subviews of the view
NSArray *subviews = [view subviews];
// Return if there are no subviews
if ([subviews count] == 0) return;
for (UIView *subview in subviews) {
NSLog(#"my subview name is: %#", subview.class); //?? is only giving my the type eg UIView, i want it to return view_player2
// List the subviews of subview
[self listSubviewsOfView:subview];
}
}
How can I actually get the name of the IBOutlet of the subview and compare it if it only starts with the word "view_"
Thanks
I've already spent 2 full days trying to figure out how to use NSViewControllers in order to create a multiview application.
Here is what I do.
I have 2 View Controllers and the MainMenu.xib's Window.
I also have an AppController that is the delegate for both View Controllers.
When I launch the app, I'm first greeted with the MainMenu.xib's Window's view which holds a button. On clicking this button, an IBAction is sent to the appController and asks for the SecondViewController to display it's nib. So far, everything's fine and the nib file is displayed correctly.
On the secondViewController, there's another button that sends another IBAction to the appController and asks for the FirstViewController to be displayed but nothing happens,
no crash, no warning... Any help would be much appreciated...
Thanks in advance for your patience...
Here is the code for the AppController.h :
#import <Foundation/Foundation.h>
#import "SecondViewController.h"
#import "FirstViewController.h"
#interface AppController : NSObject
#property (strong) IBOutlet NSWindow *mainWindow;
#property (strong) IBOutlet SecondViewController *secondViewController;
#property (strong) IBOutlet FirstViewController *firstViewController;
- (IBAction)secondButtonfromsecondViewControllerClicked:(id)sender;
- (IBAction)buttonClicked:(id)sender;
#end
and here is the code for the AppController.m :
#import "AppController.h"
#implementation AppController
#synthesize mainWindow = mainwindow;
#synthesize secondViewController;
#synthesize firstViewController;
- (IBAction)buttonClicked:(id)sender {
NSLog(#"button from second View Controller clicked");
self.secondViewController = [[SecondViewController
alloc]initWithNibName:#"SecondViewController" bundle:nil];
self.mainWindow.contentView = self.secondViewController.view;
[self.secondViewController.view setAutoresizingMask:NSViewWidthSizable |
NSViewHeightSizable];
}
- (IBAction)secondButtonfromsecondViewControllerClicked:(id)sender {
NSLog(#"button from first ViewController clicked");
self.firstViewController = [[FirstViewController
alloc]initWithNibName:#"FirstViewController" bundle:nil];
self.mainWindow.contentView = [self.firstViewController view];
}
#end
Well, anyone can help me, I just need a single view application that displays a first ViewController with a button on the first viewController that takes me to a second view controller with a second button that takes me back to my first viewcontroller... I've already spent more than a week on that... in vain... PS : I don't want any button on the mainMenu.xib window nor tabs.
here is the solution to my question then.
Here's the code for the AppDelegate.h:
// AppDelegate.h
#import <Cocoa/Cocoa.h>
#import "FirstViewController.h"
#import "SecondViewController.h"
//We need to declare the AppDelegate class as being the delegate for both
//FirstViewController and SecondViewController
#interface AppDelegate : NSObject <NSApplicationDelegate,
FirstViewControllerDelegate, SecondViewControllerDelegate>
#property (strong, nonatomic) NSWindow *window;
#property (strong) FirstViewController *firstViewController;
#property (strong) SecondViewController *secondViewController;
-(void) goToSecondView;
-(void) goToFirstView;
#end
Now, here's the AppDelegate.m:
// AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window = _window;
#synthesize firstViewController;
#synthesize secondViewController;
-(void) awakeFromNib {
[self goToFirstView];
self.firstViewController.delegate = self;
}
-(void) goToSecondView {
if (self.secondViewController ==nil) {
self.secondViewController =[[SecondViewController alloc]
initWithNibName:#"SecondViewController" bundle:nil];
}
self.window.contentView = [self.secondViewController view];
}
-(void) goToFirstView {
if (self.firstViewController ==nil) {
self.firstViewController =[[FirstViewController alloc]
initWithNibName:#"FirstViewController" bundle:nil];
}
self.window.contentView = [self.firstViewController view];
}
#end
Next we need to set delegates in the FirstViewController and the SecondViewController
// FirstViewController.h
#import <Cocoa/Cocoa.h>
#import "SecondViewController.h"
//We declare the delegation protocole:
#protocol FirstViewControllerDelegate <NSObject>
-(void)goToSecondView;
#end
#interface FirstViewController : NSViewController
- (IBAction)firstViewControllerButtonClicked:(id)sender;
#property (nonatomic, strong) id <FirstViewControllerDelegate> delegate;
#end
And here is the FirstViewController.m:
// FirstViewController.m
#import "FirstViewController.h"
#implementation FirstViewController
#synthesize delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.delegate = [NSApp delegate];
}
return self;
}
- (IBAction)firstViewControllerButtonClicked:(id)sender {
NSLog(#"button from first View Controller clicked");
if ([self.delegate respondsToSelector:#selector(goToSecondView)]) {
[self.delegate goToSecondView];
}
}
#end
Now, same thing for the SecondViewController:
// SecondViewController.h
#import <Cocoa/Cocoa.h>
#protocol SecondViewControllerDelegate <NSObject>
-(void)goToFirstView;
#end
#interface SecondViewController : NSViewController
#property (nonatomic, strong) id <SecondViewControllerDelegate> delegate;
- (IBAction)goToFirstViewControllerButtonClicked:(id)sender;
#end
And here's the SecondViewController.m:
// SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.delegate = [NSApp delegate];
}
return self;
}
- (IBAction)goToFirstViewControllerButtonClicked:(id)sender {
NSLog(#"button from Second View Controller clicked");
if ([self.delegate respondsToSelector:#selector(goToFirstView)]) {
[self.delegate goToFirstView];
}
}
#end
Well, I guess this code may be improved and if you have any suggestion, feel free to let me know. Hope it will help others.
THE PROBLEM: When the user presses a button in View2, you want View1 to appear. It's not.
STEP 1: You say that the button should be invoking an action on your AppController. Set a breakpoint (or add a diagnostic log) in that action, just to verify that it is, in fact, being invoked.
STEP 2: Think about what you want that action to do, precisely. My guess is that you want to hide View2 and show View1. Perhaps
[view2 setHidden: YES];
[view1 setHidden: NO];
(I'm not using your names here, of course.) Or you might animate the transitions, either cross-fading the views or moving them.
STEP 3: My guess is that STEP 2 will solve your problem. If it doesn't, use the debugger again to verify that view1 and view2 are not null. (If they're null, you probably have weak variables where you need them to be strong.)
STEP 4: In the unlikely event that you're still stuck, check the frames of view1 and view2. Perhaps view1 isn't where you think it is.
STEP 5: If you're still stuck, check the alphaValue of view1. Maybe you set it to be transparent, and it's being drawn transparently in the right place.
STEP 6: I bet there is no step 6!
This isn't much of an answer at the moment, however I have some concerns about your code that I wanted to work through with you.
Are you sure you have connected the outlets and actions in Interface Builder. Please verify this.
You don't need mainWindow as there is already a window property that points to the main window (verify this in Interface Builder). Also this looks wrong:
#synthesize mainWindow = mainwindow;
^
W
So dump that and just use the existing window outlet provided by Xcode.
Don't re-create the view controllers if they already exist:
if (self.secondViewController == nil)
{
self.secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController"
bundle:nil];
}
self.window.contentView = self.secondViewController.view;
I am trying to set up a very basic NSTableView with one column via the example code in Apple's documentation. I am setting it up programatically as Cocoa bindings are still a little like a dark art to me at the moment, however when I Build & Run I get no data in my app. Is there something missing from my code? (I've also hooked up my datasource and delegate via Interface Builder, so it can't be that either.)
Interface file
#import <Cocoa/Cocoa.h>
#interface RLTAppDelegate : NSObject <NSApplicationDelegate, NSTableViewDataSource, NSTableViewDelegate>
#property (assign) IBOutlet NSWindow *window;
#property (weak) IBOutlet NSScrollView *tableView;
#property (copy) NSArray *nameArray;
#end
Implementation file
#import "RLTAppDelegate.h"
#implementation RLTAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
_nameArray = [[NSArray alloc] initWithObjects:#"Ryan", #"Steven", #"Scott", nil];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return _nameArray.count;
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSTextField *result = [tableView makeViewWithIdentifier:#"withoutIcon" owner:self];
result.stringValue = [self.nameArray objectAtIndex:row];
return result;
}
#end
I think you missed
#property (weak) IBOutlet NStableView *tableview;
Connect your Outlet of tableview from xib/storyboard and dont forget to set delagate and datasource.
#property (weak) IBOutlet NSTableView *tableView;
In Interface Builder, in the Attributes inspector pane (Cmd-Opt-4), set the table view type to View Based. It is Cell Based by default.
You have to select the table view in either in the left-hand object view or by clicking on it in the editor. Notice that the first time you click on it in the editor, it will select the scroll view, so you will have to click on it a second time to get it to select the table view object.
I believe you need Xcode 4.3 or newer for the OS X 10.7 SDK, and hence view-based tables views, to be available.
I tried the same thing and it turned out that the NSTextField result was not being instantiated. I ended up using
NSTextField *result = [[NSTextField alloc]init];
result.string = [_nameArray objectAtIndex:row];
and this works just fine.
I'm new to storyboarding so the answer to this may be simplistic,
I've created a viewController in which a UITextField is present. My test is to transfer the data (text) from that text field into a viewController that is pushed onto the screen.
The coding that i have is as follows:
ViewController1.h -
#import <UIKit/UIKit.h>
#import "ViewController2.h"
#interface ViewController1 : UIViewController
#property (nonatomic, retain) IBOutlet UITextField *inputText;
#end
ViewController1.m
#import "ViewController1.h"
#implementation ViewController
#synthesize inputText;
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showTextController"]) {
ViewController2 *vc2 = [segue destinationViewController];
vc2.selectedText.text = self.inputText.text;
}
}
#end
ViewController2.h -
#import <UIKit/UIKit.h>
#interface ViewController2 : UIViewController
#property (nonatomic, retain) IBOutlet UILabel *selectedText;
#end
ViewController2.m
#import "ViewController2.h"
#implementation ViewController2
#synthesize selectedText;
#end
The segue between viewController1 and 2 in storyboard is referred to as 'showTextController'.
Is this the correct coding for something so simple? Do i need to be using 'ViewDidLoad' method along with the prepareForSegue:sender method?
It looks correct to me. In fact, this is simpler than we have had in the past since the storyboard takes care instantiating our view controller objects. One thing to note is that if you're using ARC then you shouldn't be retaining your UILabel.
Hope this helps.