NSCollectionView: Go to the next view on selection with Selected Item - xcode

I am new to OS X and have started dealing with NSCollectionView. What I am trying to do is to take show NSCollectionView with array of imageView an labels. And on the selection of the image I want to open a new viewController class. I am able to show array of images and labels in collection view but I am completely lost on how to go to new view with the selection made in NSCollectionView and how to show the image selected to the new viewController class.
I am having an NSTabView and in that I am having customView in which I am showing CollectionView. And in awakeFromNib I am doing this to populate my collectionView
-(void)awakeFromNib
{
arrItems = [[NSMutableArray alloc]init];
NSMutableArray *imageArray=[[NSMutableArray alloc]initWithObjects:#"Baby-Girl-Wallpaper-2012-7.jpg",#"Cute-Little-Baby-Girl.jpg",#"Joker_HD_Wallpaper_by_RiddleMeThisJoker.jpg",#"The-Dark-Angel-Wallpaper-HD.jpg",#"hd-wallpapers-1080p_hdwallpapersarena_dot_com.jpg",#"lion_hd_wallpaper.jpg",#"Ganesh_painting.jpg",#"krishna-wallpaper.jpg",#"LeoN_userpic_79630_fire_lion_by_alex_barrera.jpg",#"273483.png",#"japan_digital_nature-wide.jpg", nil];
NSMutableArray *imageName = [[NSMutableArray alloc]initWithObjects:#"Baby-Girl",#"Cute-Little",#"Joker",#"The-Dark",#"hd-wallpapers", #"lion", #"Ganesh", #"krishna", #"LeoN_userpic",#"273483.png",#"japan_digital", nil];
for(int i = 0; i<[imageArray count]; i++)
{
STImageCollectionModal * img1 = [[STImageCollectionModal alloc] init];
img1.image = [NSImage imageNamed:[imageArray objectAtIndex:i]];
img1.imageName = [NSString stringWithFormat:#"%#",[imageName objectAtIndex:i]];
[arrItems addObject:img1];
}
[collectionView setContent:arrItems];
}
Later I created a new class named "STCollectionView" subclass of NSCollectionView and assigned the collectionView class to "STCollectionView" and with the help of setSelectionIndexes method I tried getting the index of the selected item by this
- (void)setSelectionIndexes:(NSIndexSet *)indexes
NSLog(#"%ld",[indexes firstIndex]);
But this method is getting called twice and whenever i put "super setSelectionIndexes" it gives me garbage value.
I am searching it all over but unable to find any kind of solution. Please help..
Thank you in advance.

Your question is confusing me.What i am thinking you can do this task simply by adding UICollectionView and in UICollectionView add custom UICollectionViewCell.In custom UICollectionViewCell add UIImageView and UILabel.
in the method
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"ReuseID";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
cell.imageView.image = [UIImage imagewithNmaed:#"your Image name"];
cell.label.text = #"image Named";
return cell;
}
and in storyBoard hold CLT+drag to your UIViewController.In the method prepareForSgue Method pass data to your Next viewController.

Related

xcode Converting UITableView to UICollectionView (no valid cell)

EDIT: I should specify that this only happens when I attempt to use the UICollectionViewFlowLayout, not when I try to use a custom view. But either way nothing ever shows up on the CollectionView though it was working just fine before I converted from a TableView.)
So I've been trying to convert a UITableView that I had into a UICollectionView. So far so good. But when I try to run the app it gives me the error:
'the collection view's data source did not return a valid cell from -collectionView:cellForItemAtIndexPath: for index path {length = 2, path = 0 - 0}'
I checked all the similar questions and answers here... so in my viewDidLoad I have (tableView is actually a UICollectionView):
UINib * placeCell = [UINib nibWithNibName:#"Shops" bundle:nil];
[self.tableView registerNib:placeCell
forCellWithReuseIdentifier:CellIdentifier];
#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UICollectionView *)tableView numberOfItemsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [_entries count];
//return 5;
}
- (void)tableView:(UICollectionView *)tableView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.item == [_entries count]-1 && page > 1) {
NSLog(#"load more");
//add footer view loading
if (c_page == page) {
// _tableView.tableFooterView = nil;
}
else
{
c_page++;
[self loadPlace:c_page];
}
}
}
- (UICollectionViewCell *)tableView:(UICollectionView *)tableView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
PlaceCell *cell = (PlaceCell *)[tableView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
UINib * placeCell = [UINib nibWithNibName:#"Shops" bundle:nil];
//cell = [cellLoader instantiateWithOwner:self options:nil];
NSArray *topLevelItems = [placeCell instantiateWithOwner:self options:nil];
cell = [topLevelItems objectAtIndex:0];
Place *p = [_entries objectAtIndex:indexPath.row];
cell.placeName.text = p.PName;
NSLog (#"p:%#", p.PName")
cell.placeImg.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:p.PImage]]];
return cell;
}
I went into the xib of the UICollectionViewCell (PlaceCell) and made sure that "Cell" was the reuseidentifier. And I made sure that the datasource and delegate were connected to file's owner in the collectionView.
I also noticed that when I use a custom layout instead of the flow layout (like this one: https://github.com/ShadoFlameX/PhotoCollectionView/blob/master/CollectionViewTutorial/BHPhotoAlbumLayout.m ) it doesn't give me that error... but my collectionview still isn't populated.
So I'm wondering if there's some sort of log I can run or something I can do to figure out what's going wrong. Because I've tried all the solutions I've seen and it hasn't gotten me anywhere.
When you make a cell in a xib file you should register the xib, not the class. Also, when you register either the class or xib (or make the cell in the storyboard), you don't need an if (cell==nil) clause because your cell will never be nil when you dequeue it with dequeueReusableCellWithReuseIdentifier:forIndexPath:. You should delete that clause.
So the problem is: "Switched from UITableView to UICollectionView and no valid cell is being returned." It is really a two part answer. The crux of which is every instance of UITableView...
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 50, self.view.bounds.size.width, self.view.bounds.size.height-50)];
...you want to turn into "CollectionView"
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 50, self.view.bounds.size.width, self.view.bounds.size.height-50)];
Everything that's a "row":
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
...you'll want to turn into an "item."
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
Ultimately I had to delete the following section entirely:
UINib * placeCell = [UINib nibWithNibName:#"Shops" bundle:nil];
//cell = [cellLoader instantiateWithOwner:self options:nil];
NSArray *topLevelItems = [placeCell instantiateWithOwner:self options:nil];
cell = [topLevelItems objectAtIndex:0];
My best guess is that the Nib was being loaded twice and that Xcode was complaining that the data wasn't being loaded by the original. So getting rid of that second entry got my cells loaded and populated with data. Hope this helps someone.

Populating NSOutlineView with bindings - KVO adding of items

I've created a small test project to play with NSOutlineView before using it in one of my projects. I'm successful in displaying a list of items with children using a NSTreeController who's content is bound to an Array.
Now while I created this object it took me ages to realize that my array contents would only show up if i created them in my init method:
- (id)init
{
self = [super init];
if (self) {
results = [NSMutableArray new];
NSMutableArray *collection = [[NSMutableArray alloc] init];
// Insert code here to initialize your application
NSMutableDictionary *aDict = [[NSMutableDictionary alloc] init];
[aDict setValue:#"Activities" forKey:#"name"];
NSMutableArray *anArray = [NSMutableArray new];
for (int i; i<=3 ; i++) {
NSMutableDictionary *dict = [NSMutableDictionary new];
[dict setValue:[NSString stringWithFormat:#"Activity %d", i] forKeyPath:#"name"];
[anArray addObject:dict];
}
results = collection;
}
return self;
}
If I put the same code in applicationDidFinishLaunching it wouldn't show the items.
I'm facing the same issue now when trying to add items to the view. My understanding of using the NSTreeController is that it handles the content similar to what NSArrayController does for a NSTableView (OutlineView being a subclass and all). However, whenever I use a KV compliant method to add items to the array the items do not show up in my view.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSMutableDictionary *cDict = [[NSMutableDictionary alloc] init];
[cDict setValue:#"Calls" forKey:#"name"];
[results addObject:cDict];
[outlineView reloadData];
}
I've also tried calling reloadData on the outlineview after adding an object, but that doesn't seem to be called. What am I missing?
Here's a link to my project: https://dl.dropboxusercontent.com/u/5057512/Outline.zip
After finding this answer:
Correct way to get rearrangeObjects sent to an NSTreeController after changes to nodes in the tree?
It turns out that NSTreeController reacts to performSelector:#selector(rearrangeObjects) withObject:afterDelay:
and calling this after adding the objects lets the new objects appear.

UIImage doesn't show unless i click on my table cell

I've spent some time writing an xcode application today. I'm using a UITableView with a seperate xib for the table view cell. All is working well besides one quirky thing. In my code I set my image on the table cell xib from an array. When i run the app I've found out that the image does not appear on the table cell until I click on the table cell. And when I click on a different cell, the image on my previously selected cell disappears.
Funny thing is that I set my label on the table cell xib exactly the same way however I don't get the issue with the label.
Here is my code. I would greatly appreciate some help.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil;
cell = [tbHealthCheck dequeueReusableCellWithIdentifier:#"CONTENT"]; //all the cells in this table are named content (identifier for all cells in table)
if (cell == nil){
[[NSBundle mainBundle] loadNibNamed:#"FirstViewTableCell" owner:self options:nil];
cell = tcHealthCheck;
tcHealthCheck = nil;
}
UILabel *l1 = (UILabel *) [cell viewWithTag:0];
[l1 setText:[healthCheckCategory objectAtIndex:indexPath.row]];
l1.font = [UIFont fontWithName:#"arial" size:14];
[l1 setTextColor:[UIColor blackColor]];
UIImageView *img1 = (UIImageView *) [cell viewWithTag:1];
NSString *status = [healthCheckStatus objectAtIndex:indexPath.row];
if ([status isEqualToString:#"RED"])
{
img1.image = [UIImage imageNamed:#"red-light-badge.png"];
}
else if ([status isEqualToString:#"YELLOW"])
{
img1.image = [UIImage imageNamed:#"yellow-light-badge.png"];
}
else if ([status isEqualToString:#"GREEN"])
{
img1.image = [UIImage imageNamed:#"green-light-badge.png"];
}
return cell;
}

Xcode: iPad keyboard troubles (not that simple)

I am making an app which uses many Textfields. Most of them are inside static tableViews. I use the split view application template. Every category selected from the left panel presents a storyboard scene inside a second view on the right panel.
I just want to get rid of the keyboard with the "done" button however everything i have tried that would work on a simple view fails to work under these circumstances.
Can you please help me out with this?
p.s. I try to dismiss the keyboard inside the implementation file of the presented storyboard scene. Should i do something inside the Detail Scene of the split view controller?
Here is my Scene's code:
.h
#import <UIKit/UIKit.h>
#interface AfoEsoda : UITableViewController <UITextFieldDelegate>{
}
#property (strong, nonatomic) IBOutlet UITextField *merismataTF;
-(IBAction)hideKeyboard:(id)sender;
#end
.m
#synthesize merismataTF;
- (void)viewDidLoad
{
[super viewDidLoad];
merismataTF.delegate=self ;
}
//---------Hide Keyboard-------------------
//Tried but didn't work
-(IBAction)hideKeyboard:(id)sender {
[merismataTF resignFirstResponder];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
//Of course i do not use both methods at the same time.
EDIT:
When i set the textfield's delegate to self i get this crash:
Try implementing the textField's delegate, set the delegate to self, and in the delegate's method
- (BOOL)textFieldShouldReturn:(UITextField *)textField
set
[textField resignFirstResponder];
Another way could be going through all of the view's subviews and if it is a text field, resign first responder:
for(int i=0;i<self.view.subviews.count;i++)
{
if([[self.view.subviews objectAtIndex:i] isKindOfClass:[UITextField class]])
{
if([[self.view.subviews objectAtIndex:i] isFirstResponder])
[[self.view.subviews objectAtIndex:i] resignFirstResponder];
}}
OK, I got it. Use this with with the textFieldShouldReturn method.
So here is your answer: You have declared your text field as a property and then use alloc and init it over and over again for each cell. Probably it only works properly for the last row.
Here is an example of how your cellForRow method should look like:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ static NSString *cellIdentifier = #"My cell identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UITextField *newTextField;
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
newTextField = [[UITextField alloc] initWithFrame:CGRectMake:(0,0,25,25)];
newTextField.tag = 1;
newTextField.delegate = self;
[cell.contentView addSubview:newTextField];
}
else
newTextField = (UITextField *)[cell.contentView viewWithTag:1];
And then, if you need the textField's value for a certaing row, simply use:
UITextField *someTextField = (UITextField *)[[tableView cellForRowAtIndexPath:indexPath].contentView viewWithTag:1];
NSLog(#"textField.text = %#", someTextField.text);

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