Objective-J Cappuccino want a list of buttons on main menu, when I click the panel refreshes with UI of button selected - cappuccino

Dear all, I am new to objective-j/c and cappuccino not really sure how this all fits together.
The code below is taken from http://github.com/jfahrenkrug/CappuccinoLocations1
What I need to do is:
I need a landing main menu which is a CPView called ie MainView with five or so buttons, when you click on the LocationButton on MainView is replaces MainView by with LocationView, which displays the contents of jfahrenkrug's work. A similar effect will happen with each other button.
What is the correct Objective-c/j way of handling this approach?
#import <Foundation/CPObject.j>
#import "src/Location/LocationView.j"
#implementation AppController : CPObject
{
LocationView locationView;
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
mainContentView = [theWindow locationView],
bounds = [locationView bounds];
[mainContentView setBackgroundColor:[CPColor colorWithRed:212.0 /255.0 green:221.0/ 255.0 blue:230.0/255.0 alpha:1.0]];
locationView = [[LocationView alloc] initWithFrame:CGRectMake(0,0,920.0,590.0)];
[locationView setCenter:[mainContentView center]];
[locationView setBackgroundColor:[CPColor whiteColor]]
[locationView setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin | CPViewMinYMargin | CPViewMaxYMargin];
var shadow = [[CPShadowView alloc] initWithFrame:CGRectMakeZero()];
[shadow setFrameForContentFrame:[locationView frame]];
[shadow setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin | CPViewMinYMargin | CPViewMaxYMargin];
[mainContentView addSubview:shadow];
[mainContentView addSubview:locationView];
[theWindow orderFront:self];
}
Now we have the locationView.j
#import "LocationsController.j"
#import "LocationListView.j"
#import "MapController.j"
#import "LocationsToolbar.j"
#import "LocationDetailView.j"
#import "LocationDetailController.j"
#implementation LocationView : CPView
{
LocationsController locationsController;
LocationListView locationListView;
MapController mapController;
MKMapView mapView;
CPTextField coordinatesLabel;
LocationsToolbar locationsToolbar;
LocationDetailView locationDetailView;
LocationDetailController locationDetailController;
CPTextField searchField;
// id delegate #accessors;
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
if(self){
locationsController = [[LocationsController alloc] init];
[locationsController loadExampleLocations];
locationListView = [[LocationListView alloc] initWithFrame:CGRectMake(0.0,0.0,226.0,400.0)];
[locationListView setContent:[locationsController locations]];
[locationListView setDelegate:locationsController];
[locationsController setLocationListView:locationListView];
var locationScrollView = [[CPScrollView alloc] initWithFrame:CGRectMake(10.0,65.0,243.0,400.0)];
[locationScrollView setDocumentView:locationListView];
[locationScrollView setAutohidesScrollers:YES];
[[locationScrollView self] setBackgroundColor:[CPColor whiteColor]];
[self addSubview:locationScrollView];
mapController = [[MapController alloc] init];
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(510,65,400,400) apiKey:'' ];
[mapView setDelegate:self];
mapController.mapView = mapView;
[self addSubview:mapView];
coordinatesLabel = [[CPTextField alloc] initWithFrame:CGRectMake(510,465,200,35)];
[coordinatesLabel setTextColor:[CPColor colorWithHexString:#"009900"]];
[coordinatesLabel setFont:[CPFont systemFontOfSize:14.0]];
[coordinatesLabel setEditable:NO];
[coordinatesLabel setStringValue:#"-/-"];
[mapController setCoordinatesLabel:coordinatesLabel];
[self addSubview:coordinatesLabel];
locationsToolbar = [[LocationsToolbar alloc] initWithFrame:CGRectMake(10.0,467.0,226.0,25.0)];
[locationsToolbar setDelegate:locationsController];
[self addSubview:locationsToolbar];
locationDetailController = [[LocationDetailController alloc] init];
locationDetailController.mapController = mapController;
locationsController.locationDetailController = locationDetailController;
[mapController setDelegate:locationDetailController];
locationDetailView = [[LocationDetailView alloc] initWithFrame:CGRectMake(510,490,400,90)];
[locationDetailView setDelegate:locationDetailController];
[locationDetailController setLocationDetailView:locationDetailView];
[self addSubview:locationDetailView];
searchField = [CPTextField roundedTextFieldWithStringValue:#"" placeholder:#"Location" width:200.0];
[searchField setFrameOrigin:CGPointMake(510.0,35.0)];
[searchField setDelegate:self];
[self addSubview:searchField];
var searchButton = [[CPButton alloc] initWithFrame:CGRectMake(710.0,37.0,60.0,24.0)];
[searchButton setTitle:"Search"];
[searchButton setTarget:self];
[searchButton setAction:#selector(searchLocation)];
[self addSubview:searchButton];
}
return self;
}

I'm not sure I understand your question but essentially a window has a default view called the content view. You get it like so:
var contentView = [theWindow contentView];
To the content view you can add subviews (and buttons).
[contentView addSubview:myLocationView];
The location of those subviews is determined by the 'frame' of the subview.
[myLocationView setFrame:CGRectMake(10, 10, 100, 100)];
You can replace the content view's subviews with something else by either removing the previous views or using the setSubviews message.
[contentView setSubviews:[aButton, anotherButton]];
So essentially if you want to swap out one view for another, call 'setSubviews' on its super view with the new views you want. Hope that helps to get you started.

Related

NSButton Toggle : OnClick title get removed on OSX 10.11

I am using a Toggle button in XIB,
in AwakeFromNib :I set title and BG image of the button.
Code works very well till OSX 10.10.5 and below but on higher versions when I click on button the text gets removed.
Set attributed Title
[self.deleteButton setWantsLayer:YES];
self.deleteButton.layer.backgroundColor = [self setButtonBGColor];
[self setButtonTitleFor:self.deleteButton
toString:#"Delete"];
[self.deleteButton setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawOnSetNeedsDisplay];
- (void)setButtonTitleFor:(NSButton*)button toString:(NSString*)title
{
NSAttributedString *attrString = [self getAttributedStringForString:title];
[button setAttributedTitle:attrString];
}
Any idea hat should be done.
So finally got it right
Subclassing NSButtonCell helped me out
RPButtonTextTopCell.h
#interface RPButtonTextTopCell : NSButtonCell
#end
RPButtonTextTopCell.m
#implementation RPButtonTextTopCell
-(id) init
{
self = [super init];
if (self) {
}
return self;
}
-(id) initWithCoder:(NSCoder *)decoder
{
return [super initWithCoder:decoder];
}
-(id) initTextCell:(NSString *)string
{
return [super initTextCell:string];
}
-(NSRect)titleRectForBounds:(NSRect)theRect
{
NSRect titleFrame = [super titleRectForBounds:theRect];
NSSize titleSize = [[self attributedStringValue] size];
titleFrame.origin.y = (theRect.origin.y - (theRect.size.height-titleSize.height)*0.5) + 5;
return titleFrame;
}
#end
Utilizing This Custom Class
RPButtonTextTopCell *deleteCell = [[RPButtonTextTopCell alloc] init];
deleteCell.backgroundColor = [self setNSButtonBGColor];
[self.deleteButton setCell:deleteCell];
[self setButtonTitleFor:self.deleteButton
toString:#"Delete"];
[self.deleteButton setAction:#selector(deleteButtonClicked:)];
[self.deleteButton setTarget:self];
and its solved....

How do I implement frameForAlignmentRect:/alignmentRectForFrame: such that the frame outside the alignment rect encapsulates those of subviews?

So I now have my Auto Layout-based container working, for the most part. On 10.8 (I need to run on 10.7 and newer), I see this:
Notice how the sides of the NSProgressIndicator and NSPopUpButton are clipped.
After some experimentation, I found that overriding alignmentRectInsets and returning 50 pixels of insets on all sides shows no clipping:
In both cases, the controls are bound to the left and right edges of the container view alignment rect with H:|[view]|. I imagine this will happen on other versions of OS X too, but it's most noticeable here (and as of writing I only have access to 10.8 and 10.10 installs).
Now, using alignment rect insets of 50 pixels on each side sounds wrong. I don't think there'd be any control that would need more than 50 pixels, but I'd rather do these correctly. So my question is: How do I implement the alignmentRectForFrame: and frameForAlignmentRect: selectors to properly account for the frames and alignment rects of the subviews?
Right now, I'm thinking to force a layout and then observe the frames and alignment rects of each subview, assuming that alignment rect (0, 0) of my last subview (the subviews are arranged linearly) will be at alignment rect (0, 0) of the container view. But I'm not sure if this approach is sufficient to handle all cases, and I'm not sure if I can invert the operation in the same way that these two selectors require. Subtraction, maybe?
If what I described above is the solution, could I do that with alignmentRectInsets, or must the insets returned by that method never change during the lifetime of the view?
Or is the second screenshot showing a scenario that Interface Builder won't reproduce, and thus I assume is "wrong" from a guidelines standpoint?
In the sample program below, start without a command-line argument to simulate the first screenshot, and start with an argument to simulate the second screenshot. Check the Spaced checkbox to add spacing to the views.
Thanks!
// 17 august 2015
#import <Cocoa/Cocoa.h>
BOOL useInsets = NO;
#interface ContainerView : NSView
#end
#implementation ContainerView
- (NSEdgeInsets)alignmentRectInsets
{
if (useInsets)
return NSEdgeInsetsMake(50, 50, 50, 50);
return [super alignmentRectInsets];
}
#end
NSWindow *mainwin;
NSView *containerView;
NSProgressIndicator *progressbar;
NSPopUpButton *popupbutton;
NSButton *checkbox;
void addConstraints(NSView *view, NSString *constraint, NSDictionary *views)
{
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:constraint
options:0
metrics:nil
views:views];
[view addConstraints:constraints];
}
void relayout(BOOL spaced)
{
[containerView removeConstraints:[containerView constraints]];
NSDictionary *views = #{
#"pbar": progressbar,
#"pbutton": popupbutton,
#"checkbox": checkbox,
};
NSString *vconstraint = #"V:|[pbar][pbutton][checkbox]|";
if (spaced)
vconstraint = #"V:|[pbar]-[pbutton]-[checkbox]|";
addConstraints(containerView, vconstraint, views);
addConstraints(containerView, #"H:|[pbar]|", views);
addConstraints(containerView, #"H:|[pbutton]|", views);
addConstraints(containerView, #"H:|[checkbox]|", views);
NSView *contentView = [mainwin contentView];
[contentView removeConstraints:[contentView constraints]];
NSString *base = #":|[view]|";
if (spaced)
base = #":|-[view]-|";
views = #{
#"view": containerView,
};
addConstraints(contentView, [#"H" stringByAppendingString:base], views);
addConstraints(contentView, [#"V" stringByAppendingString:base], views);
}
#interface appDelegate : NSObject<NSApplicationDelegate>
#end
#implementation appDelegate
- (IBAction)onChecked:(id)sender
{
relayout([checkbox state] == NSOnState);
}
- (void)applicationDidFinishLaunching:(NSNotification *)note
{
mainwin = [[NSWindow alloc]
initWithContentRect:NSMakeRect(0, 0, 320, 240)
styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)
backing:NSBackingStoreBuffered
defer:YES];
NSView *contentView = [mainwin contentView];
containerView = [[ContainerView alloc] initWithFrame:NSZeroRect];
[containerView setTranslatesAutoresizingMaskIntoConstraints:NO];
progressbar = [[NSProgressIndicator alloc] initWithFrame:NSZeroRect];
[progressbar setControlSize:NSRegularControlSize];
[progressbar setBezeled:YES];
[progressbar setStyle:NSProgressIndicatorBarStyle];
[progressbar setIndeterminate:NO];
[progressbar setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:progressbar];
popupbutton = [[NSPopUpButton alloc] initWithFrame:NSZeroRect];
[popupbutton setPreferredEdge:NSMinYEdge];
NSPopUpButtonCell *pbcell = (NSPopUpButtonCell *) [popupbutton cell];
[pbcell setArrowPosition:NSPopUpArrowAtBottom];
[popupbutton addItemWithTitle:#"Item 1"];
[popupbutton addItemWithTitle:#"Item 2"];
[popupbutton setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:popupbutton];
checkbox = [[NSButton alloc] initWithFrame:NSZeroRect];
[checkbox setTitle:#"Spaced"];
[checkbox setButtonType:NSSwitchButton];
[checkbox setBordered:NO];
[checkbox setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSRegularControlSize]]];
[checkbox setTarget:self];
[checkbox setAction:#selector(onChecked:)];
[checkbox setTranslatesAutoresizingMaskIntoConstraints:NO];
[containerView addSubview:checkbox];
[contentView addSubview:containerView];
relayout(NO);
[mainwin cascadeTopLeftFromPoint:NSMakePoint(20, 20)];
[mainwin makeKeyAndOrderFront:mainwin];
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)app
{
return YES;
}
#end
int main(int argc, char *argv[])
{
useInsets = (argc > 1);
NSApplication *app = [NSApplication sharedApplication];
[app setActivationPolicy:NSApplicationActivationPolicyRegular];
[app setDelegate:[appDelegate new]];
[app run];
return 0;
}

Getting a CollectionView delegate to load properly

(Let me first put the error up here so that I don't forget it: could not dequeue a view of kind: UICollectionElementKindCell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard)
I've got a regular UICollectionViewController that loads just fine. But I also have another controller (UserViewController) that loads a CollectionView delegate (UserPlaceViewController).
I get really confused with what I have to load in the delegate and what I have to load in the current controller. But anyway here's the delegate as-is:
#import "UserPlaceViewController.h"
#interface UserPlaceViewController ()
#end
#implementation UserPlaceViewController
#synthesize placeArray, placeTable;
- (void)viewDidLoad
{
[super viewDidLoad];
// placeTable.delegate = self;
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(145, 150);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
placeTable = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
//self.collectionView.frame = CGRectMake(10, 120, self.view.bounds.size.width-20, self.view.bounds.size.height-50);
placeTable.autoresizesSubviews = YES;
placeTable.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
//placeTable.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
placeTable.scrollEnabled = YES;
self.view = placeTable;
NSLog(#"%lu", (unsigned long)[placeArray count]);
}
That's basically the whole thing. Couple other things at the end... but that's it for the most part.
And here are the relevent parts of the ViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES animated:YES];
UserPlaceViewController *collectionView = [[UserPlaceViewController alloc] initWithNibName:#"UserPlace" bundle:nil];
UINib * placeCell = [UINib nibWithNibName:#"Shops" bundle:nil];
[collectionView.placeTable registerNib:placeCell forCellWithReuseIdentifier:cellIdentifier];
- (void) fetchedData: (NSData *) responseData
{
UserPlaceViewController * uptvLike = [[UserPlaceViewController alloc] init];
if (IS_IPHONE5) {
uptvLike.view.frame = CGRectMake(0, 0, 320, 300);
}
else
{
uptvLike.view.frame = CGRectMake(0, 0, 320, 200);
}
uptvLike.placeTable.delegate = self;
uptvLike.placeTable.dataSource = self;
uptvLike.placeTable.layer.borderWidth = 1.0f;
uptvLike.placeTable.layer.borderColor = [UIColor colorWithRed:5/255.0f green:96/255.0f blue:255/255.0f alpha:1.0f].CGColor;
[uptvLike.placeTable reloadData];
[self.scrollView addSubview:uptvLike.view];
}
And finally:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PlaceCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
Place * p = [placeArray objectAtIndex:indexPath.item];
cell.placeName.text = p.PName;
cell.placeImg.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:p.PImage]]];
return cell;
}
Like I said: I know how a UICollectionView is supposed to work. I've got one running. I know you have to register a nib or class in viewDidLoad (I've registered a Nib.) But I'm confused over how exactly to load this delegate and where to load what. For example I see that I'm initialising the collectionview in both the delegate and the view controller. I'm also confused about WHERE exactly I should load the nib... (delegates give me a headache...)
So what the hell... It's raining. I figured I'd ask.
Ok. You want a UICollectionView but you also want to have a lot of regular "View" items on the same screen? Two things are important:
1. You don't need two ViewControllers. You just need to load what would normally be your UICollectionViewController as a regular ViewController:
#interface UserViewController : UIViewController <UICollectionViewDataSource, UIScrollViewDelegate>
2. Once that's done you can load your collectionview on TOP of that view:
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(145, 150);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:flowLayout];
[self.scrollView addSubview:self.collectionView];
[self.view addSubview:HUD];
UINib * placeCell = [UINib nibWithNibName:#"UserCell" bundle:nil];
[self.collectionView registerNib:placeCell forCellWithReuseIdentifier:#"Cell"];
The rest is just your standard CollectionView stuff.

adding subviews to an NSView to have a chess-like grid

I am trying to create a Cocoa UI that consists of two sets of squares (chess-like grids) that will assume different colours while an underlying algorithm is running. When the execution of the algorithm comes to an end, the UI should be able to handle clicks, panning and other gestures.
The hierarchy I have so far is the following (please check the attached code for specifics):
1) the main window that is the window of a window controller
2) a split view with two custom views, mainView and sideView (each one would hold a set of squares)
3) two view controllers (mainViewController and sideViewController)
I would like to be able to load the squares as subviews of mainView and sideView.
I thought of having another custom view, say SquareView with another nib file. My questions would be:
a) how do I create this SquareView so that it can be used to create the squares that will be added to mainView and sideView as subviews to form chess-like grids?
b) how do I add subviews to mainView and sideView to built the two grids? For the sake of simplicity, let's assume there would be four non-overlapping squares for each of the previously mentioned views.
Thank you!
MainView.m
#import "MainView.h"
#implementation MainView
- (void)drawRect:(NSRect)TheRect
{
[[NSColor grayColor] set];
[NSBezierPath fillRect:[self bounds]];
}
SideView.m
#import "SideView.h"
#implementation MainView
- (void)drawRect:(NSRect)TheRect
{
[[NSColor whiteColor] set];
[NSBezierPath fillRect:[self bounds]];
}
MainWindowController.h
#import <Cocoa/Cocoa.h>
#class SideViewController;
#class MainViewController;
#interface MainWindowController : NSWindowController
{
IBOutlet NSSplitView* oMainSplitView;
SideViewController* sideViewController;
MainViewController* mainViewController;
}
#end
MainWindowController.m
#import "MainWindowController.h"
#import "SideViewController.h"
#import "MainViewController.h"
#implementation MainWindowController
- (void)windowDidLoad
{
sideViewController = [[SideViewController alloc] initWithNibName:#"SideView" bundle:nil];
NSView* splitViewLeftView = [[oMainSplitView subviews] objectAtIndex:0];
NSView* sideView = [sideViewController view];
[sideView setFrame:[splitViewLeftView bounds]];
[sideView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[splitViewLeftView addSubview:sideView];
mainViewController = [[MainViewController alloc] initWithNibName:#"MainView" bundle:nil];
NSView* splitViewRightView = [[oMainSplitView subviews] objectAtIndex:1];
NSView* mainView = [mainViewController view];
[mainView setFrame:[splitViewRightView bounds]];
[mainView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[splitViewRightView addSubview:mainView];
}
You can make this as simple or as complicated as you desire: simple? do everything you want in MainView's drawRect method; complex: nest NSViews (or NSCell's, or NSBox's, etc.) and have each one draw itself.
Personally, I'd vote to keep it simpleā€¦
a) I think the easiest way would be to create a matrix of NSBoxes, which you could do in code or in IB. Having the squares in a matrix would make it easy to loop through them or access specific ones.
b) I'm not sure what your question is here -- you would do it just as you did in your posted code, using [mainView addSubview:squareMatrix];
After Edit: Actually, it looks like IB won't let you embed NSBoxes in a matrix. In the past, I've made a matrix of subclassed NSButtonCells (to allow background color with no border) that had a grid of 64x64 cells that were clickable and would change color with those clicks. I don't know if you want a fixed number of cells in your views, or do you need to dynamically change the number? Something like this could work for you I think -- I actually created this in code, because IB was really slow in updating with that many cells.
Here is what I did. In my case, I needed cells with no border but with background color, so I had to subclass NSButtonCell, like this:
-(id)initWithRGBAlpha:(NSArray *)rgbAlpha {
if (self == [super init]) {
NSColor *color = [NSColor colorWithCalibratedRed:[[rgbAlpha objectAtIndex:0]doubleValue]
green:[[rgbAlpha objectAtIndex:1]doubleValue]
blue:[[rgbAlpha objectAtIndex:2]doubleValue]
alpha:[[rgbAlpha objectAtIndex:3]doubleValue]];
[self setBackgroundColor:color];
[self setTitle:#""];
[self setBordered:NO];
[self setTag:0];
[self setImageScaling:3];
return self;
}else{
return nil;
}
}
-(void) setState:(NSInteger)value {
if (value == 1) {
self.backgroundColor = self.selectedColor;
[super setState:value];
}else {
self.backgroundColor = self.backgroundColor;
[super setState:value];
}
}
-(void) setBackgroundColor:(NSColor *)color {
backgroundColor = color;
selectedColor = [color colorWithAlphaComponent:.75];
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[super encodeWithCoder:encoder];
[encoder encodeObject:self.backgroundColor forKey:#"bColor"];
}
- (id)initWithCoder:(NSCoder *)decoder {
[super initWithCoder:decoder];
self.backgroundColor = [decoder decodeObjectForKey:#"bColor"];
return self;
}
I created the matrix in code, like so:
#implementation RDMatrix
-(void) initWithParentView:(NSView *) cv {
NSNumber *one = [NSNumber numberWithInt:1];
NSArray *colors = [NSArray arrayWithObjects:one,one,one,one,nil];
RDButtonCell *theCell = [[RDButtonCell alloc ]initWithRGBAlpha:colors];
[self initWithFrame:NSMakeRect(200,100,1,1) mode:2 prototype:theCell numberOfRows:64 numberOfColumns:64];
[self setSelectionByRect:TRUE];
[self setCellSize:NSMakeSize(8,8)];
[self sizeToCells];
self.target = self;
self.action = #selector(matrixClick:);
self.backgroundColor = [NSColor lightGrayColor];
self.drawsBackground = TRUE;
self.autoresizingMask = 8;
self.allowsEmptySelection = TRUE;
[cv addSubview:self];
}
-(void) matrixClick: (id) sender {
for (RDButtonCell *aCell in self.selectedCells){
if ([self.selectedCells count] < 64) {
aCell.backgroundColor = [NSColor colorWithCalibratedRed:1 green:0 blue:0 alpha:1];
}else{
aCell.backgroundColor = [NSColor colorWithCalibratedRed:0 green:.5 blue:1 alpha:1];
}
}
[self deselectAllCells];
}
#end

UITabBarController + UINavigationController problem xcode project

I have a problem, I have created a project window based application in xcode, then I create a UITabBarController that manages two views all programmatically, the second view is a tableView and I want to see in the top a UINavigationController, I have tried a lot but I don't know how to have a UINavigationController in the second view. this is the code:
ProjectAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Creo una tabBarController
UITabBarController *tabBarController = [[UITabBarController alloc] init];
//Create the two view controllers
UIViewController *vc1 = [[Visuale1ViewController alloc] init];
UIViewController *vc2 = [[Visuale2ViewController alloc] init];
//Make an array containing the two view controllers
NSArray *viewControllers = [NSArray arrayWithObjects:vc1, vc2, nil];
//The viewControllers array retains vc1 and vc2, we can release
//our ownership of them in this method
[vc1 release];
[vc2 release];
//Attach them to the tab bar controller
[tabBarController setViewControllers:viewControllers];
//Setto la tabBarController come rootViewController di window
[window setRootViewController:tabBarController];
//The window retain tabBarController, possiamo lasciare il nostro riferimento
[tabBarController release];
[self.window makeKeyAndVisible];
return YES;
}
Visuale1ViewController.h
#implementation Visuale1ViewController
- (id)init{
[super initWithNibName:#"Visuale1ViewController" bundle:nil];
//Get the tab bar item
UITabBarItem *tbi = [self tabBarItem];
//Give it a label
[tbi setTitle:#"Visuale 1"];
return self;
}
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle {
return [self init];
}
Visuale2ViewController.h
#implementation AnswerViewController
- (id)init{
//Call the superclass's designated initializer
/*[super initWithNibName:nil
bundle:nil];*/
[super initWithStyle:UITableViewStyleGrouped];
answers = [[NSMutableArray alloc] init];
for (int i = 0; i<10 ; i++) {
[answers addObject:[Answer DefaultAnswer]];
}
//Get the tab bar item
UITabBarItem *tbi = [self tabBarItem];
//Give it a laber
[tbi setTitle:#"Visuale 2"];
return self;
}
- (id)initWithStyle:(UITableViewStyle)style{
return [self init];
}
//All below are all methods to work the table view, and all go well, the only problem it's the UINavigationController, to manage then the detail of the table...
Now I want to know how I can put a UINavigationController in the second view. I try do this, in ProjectAppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Creo una tabBarController
UITabBarController *tabBarController = [[UITabBarController alloc] init];
//Create the two view controllers
UIViewController *vc1 = [[Visuale1ViewController alloc] init];
UIViewController *vc2 = [[Visuale2ViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vc2];
//Make an array containing the two view controllers
NSArray *viewControllers = [NSArray arrayWithObjects:vc1, navController, nil];
//The viewControllers array retains vc1 and vc2, we can release
//our ownership of them in this method
[vc1 release];
[vc2 release];
//Attach them to the tab bar controller
[tabBarController setViewControllers:viewControllers];
//Setto la tabBarController come rootViewController di window
[window setRootViewController:tabBarController];
}
In this way I can visualize the NavigationBar, but I lost the name of the SecondTabBar. Sorry for my english, how I can do this?
Yes in the second view you have to set title as
[self.navigationItem setTitle:#"Visuale2"];
For TabBar title-
UITabBar *tabBar = [self.tabBarController tabBar];
NSArray *tabBarItems = [tabBar items];
UITabBarItem *secondTabBarItem = [tabBarItems objectAtIndex:1];
[secondTabBarItem setTitle:#"Visuale2"];
I left the code as it was and I added in init Visale2ViewController this:
UIImage *i = [UIImage imageNamed:#"Hypno.png"];
[tbi setImage:i];
and now in can see the text Visuale2 in tabBar and the image...i don't know why...
You need to set the tabBarItem property for your UINavigationController. Something like this.
UITabBarItem *tabItem = [[UITabBarItem alloc] initWithTitle:#"Visuale 2" image:nil tag:1];
UIViewController *vc2 = [[Visuale2ViewController alloc] init];
navController = [[UINavigationController alloc] initWithRootViewController:vc2];
navController.tabBarItem = tabItem;
After looking at it,the scenario seems to be same like me.What I faced for the first time when doing Tab+Navigation.
I am sure that there is some problem with your Tab+Navigation based application. Although it shows the Tab as well as navigation are not able to navigate the basic flow.And it is very difficult to solve your problem with such less code.
Instead of this, I had an alternate solution for the same:
Once you have a tab bar in a XIB, the easiest way to approach this is to drag a UINavigationController object over from the Library window (looks like a left nav bar button on a gold background) into the Tree View for your tab bar (the text only view, not the GUI). Place it under the tab bar, then drag your existing view controller under the tab bar controller instead of under the tab bar.
When you go to view that tab you should then see a navigation bar on the top of it... if you are loading the navigation controller from another xib, you'll modify the nav bar in the tab bar xib.
else you can below you can follow the best url for the same:
http://books.google.co.in/books?id=2yYlm_2ktFYC&pg=PA179&lpg=PA179&dq=navigation+with+the+tab+based+application+iphoneSDK&source=bl&ots=nf2YYjX5Am&sig=COpHj9wOtsDChQBglpsljSTsElw&hl=en&ei=3ZoFTeGSOI_tsgbc_Iz6CQ&sa=X&oi=book_result&ct=result&resnum=6&ved=0CDAQ6AEwBQ#v=onepage&q&f=false
http://www.youtube.com/watch?v=LBnPfAtswgw
Hope this will surely solve your problem.

Resources