NSCollectionViewItems don't reload when scrolling <OSX - Objective C> - objective-c

I'm new to learning Objective-C and I have a problem with NSCollectionView which I couldn't find any ways to resolve it.
My problem is:
I wrote a button event to create a NSCollectionView named thoughtCollectionView and added onto my contentView to display NSCollectionViewItems.
When I run the simulator, items look okay, but they don't reload when I scroll.
Here's my code:
MainViewController.m
- (void)thoughtShow{
// Add Collection View
thoughtCollectionView = [[ThoughtCollection alloc] initWithFrame:NSMakeRect(0, 0, contentWidth, contentHeight)];
NSCollectionViewFlowLayout *layout = [[NSCollectionViewFlowLayout alloc] init];
[thoughtCollectionView setCollectionViewLayout:layout];
[layout setScrollDirection:NSCollectionViewScrollDirectionVertical];
layout.itemSize = NSMakeSize(50, 50);
layout.minimumInteritemSpacing = 20;
layout.sectionInset = NSEdgeInsetsMake(20, 20, 20, 20);
[thoughtCollectionView registerClass:ThoughtItems.self forItemWithIdentifier:#"ThoughtItems"];
thoughtScrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0, 0, contentWidth, contentHeight)];
thoughtScrollView.documentView = thoughtCollectionView;
[contentView addSubview:thoughtScrollView];
[thoughtCollectionView reloadData];
[thoughtCollectionView setNeedsDisplay:YES];
[thoughtCollectionView layoutSubtreeIfNeeded];
}
MainViewController.h
#interface MainViewController : NSViewController <NSCollectionViewDelegateFlowLayout, NSCollectionViewDelegate, NSCollectionViewDataSource>
#end
ThoughtCollectionView.h
#interface ThoughtCollection : NSCollectionView <NSCollectionViewDataSource, NSCollectionViewDelegate, NSCollectionViewDelegateFlowLayout>
{
NSMutableArray * ar;
}
#end
ThoughtCollectionView.m
#implementation ThoughtCollection
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath{
ThoughtItems *item = [collectionView makeItemWithIdentifier:#"ThoughtItems" forIndexPath:indexPath];
NSLog(#"Reloading item");
return item;
}
- (void)collectionView:(NSCollectionView *)collectionView willDisplayItem:(nonnull NSCollectionViewItem *)item forRepresentedObjectAtIndexPath:(nonnull NSIndexPath *)indexPath{
}
- (void)collectionView:(NSCollectionView *)collectionView didEndDisplayingItem:(nonnull NSCollectionViewItem *)item forRepresentedObjectAtIndexPath:(nonnull NSIndexPath *)indexPath{
}
- (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
NSLog(#"Collection view count : %lu", [ar count]);
return [ar count];
}
- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView{
return 1;
}
-(BOOL)shouldInvalidateLayoutForBoundsChange:(NSRect)newBounds
{
return YES;
}
- (void)viewDidMoveToWindow {
NSLog(#"My collection View");
self.delegate = self;
self.dataSource = self;
ar = [[NSMutableArray alloc] init];
for (int n = 0; n < 1000; n++) {
[ar addObject:#"Hello"];
}
[self reloadData];
[self setNeedsDisplay:YES];
[self layoutSubtreeIfNeeded];
}
#end
Simulator display:
enter image description here
Scroll:
enter image description here
ThoughtItem.m
#import "ThoughtItems.h"
#interface ThoughtItems ()
#end
#implementation ThoughtItems
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setWantsLayer:YES];
[self.view.layer setBackgroundColor:[[NSColor orangeColor] CGColor]];
}
#end
ThoughtItem.h
#import <Cocoa/Cocoa.h>
#interface ThoughtItems : NSCollectionViewItem
#end

I found out that what's the problem with the CollectionItem.
I have to add an Object in the ThoughtItem.xib file, then change the object class name to "ThoughtItem".
And I change -(void)viewDidMoveToWindow to a method which I can call it from MainViewController.
(or create NSCollectionView in the MainViewController is a way to solve it too)
Then all the problems are solved!

Related

how to create custom UICollectionViewCell

I have a UICollectionView and Im trying to set a label and an image in the collectionViewCell. Unfortunately I cant seem to get any labels to display or anything else for that matter.
Here is my code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
if(indexPath.item %2 == 0){
cell.backgroundColor=[UIColor blueColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
else {
cell.backgroundColor=[UIColor redColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
}
Unfortunately no label is being displayed and neither is the text in the label.
Updated: I've added the rest of the code from this class file.
#import "ContainerListController.h"
#import "ContainerController.h"
#import "ContainerList.h"
#implementation ContainerListController
//Deallocate temp variables
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
//Initiate objects
- (id)init {
if (self = [super initWithTitle:LocStr(#"CONTAINER_LIST_TITLE") navBarHidden:NO]) {
m_paths = [ContainerList shared].paths;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(onContainerListDidChange)
name:kSDKLauncherContainerListDidChange object:nil];
}
return self;
}
//Load all the views.
- (void)loadView {
//Allocate a UI view
self.view = [[UIView alloc] init];
//Create flow layout
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
//Force Horizontal Scroll
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
layout.minimumInteritemSpacing =[[UIScreen mainScreen] bounds].size.width;
layout.minimumLineSpacing=0.0;
//Create Collection
UICollectionView *coll =[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
//Allocations
m_coll = coll;
coll.dataSource =self;
coll.delegate =self;
coll.pagingEnabled = YES;
coll.collectionViewLayout = layout;
//Customize Cells
[coll registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[coll setBackgroundColor:[UIColor orangeColor]];
[layout invalidateLayout];
//Create the subview
[self.view addSubview:coll];
//set minimum spacing
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
NSLog(#"Changed to landscape Spacing");
layout.minimumLineSpacing = 100.0f;
layout.minimumInteritemSpacing = 100.0f;
}
else{
layout.minimumLineSpacing = 40.0f;
layout.minimumInteritemSpacing = 40.0f;
}*/
//Old Layout
//UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
//m_table = table;
//table.dataSource = self;
//table.delegate = self;
//[self.view addSubview:table];
}
- (void)onContainerListDidChange {
m_paths = [ContainerList shared].paths;
[m_table reloadData];
[m_coll reloadData];
}
//Debugging components function
/*-(void)printComps:(NSArray* ) components{
for (NSInteger i =0; i<16; i++) {
NSString * item;
item=components[i];
}
}*/
//old tableview cell
- (UITableViewCell *)
tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:nil];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
cell.textLabel.text = (components == nil || components.count == 0) ?
#"" : components.lastObject;
return cell;
}
//Old tableView
- (void)
tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];
if (c != nil) {
[self.navigationController pushViewController:c animated:YES];
}
NSLog(#"Selected an item");
}
//old TableView count for epubs
- (NSInteger)
tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section{
return m_paths.count;
}
- (void)viewDidLayoutSubviews {
//m_table.frame = self.view.bounds;
m_coll.frame = self.view.bounds;
}
//Collection View Cell Data Allocation
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
//UICollectionViewCell *content = [[UICollectionViewCell alloc] init];
if(indexPath.item %2 == 0){
cell.backgroundColor=[UIColor blueColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
else {
cell.backgroundColor=[UIColor redColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
NSString *Title = components.lastObject;
NSLog(#"Title: %#",Title);
NSString *Titletest = components.lastObject;
NSInteger comp1 = components.count;
NSString *comps = #"components";
NSLog(#"There are: %ld %#", (long)comp1,comps);
NSLog(#"Title: %#",Titletest);
for (NSInteger i =0; i<15; i++) {
NSString * item;
item=components[i];
NSLog(#"Component:%ld %#",(long)i,components[i]);
}
return cell;
}
//Collection View Cell Data De-Allocation
- (void)
collectionView:(UICollectionView *)collectionView
numberofItemsInSection:(NSIndexPath *)indexPath{
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];
if(c !=nil){
[self.navigationController pushViewController:c animated:YES];
}
}
//Collection
-(NSInteger)
collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section{
return m_paths.count;
}
//Set Collection View Cell Size
-(CGSize)
collectionView:(UICollectionView *) collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
//Set Landscape size of cells
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-360;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-60;
NSLog(#"Is Landscape");
return CGSizeMake(cellWidth, cellHeigt);
}
//Set Potrait size of cells
else{
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-60;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-160;
NSLog(#"Is Portrait");
return CGSizeMake(cellWidth, cellHeigt);
}*/
return CGSizeMake(collectionView.bounds.size.width, collectionView.bounds.size.height);
}
//Collection View Cell Position
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
if(UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)){
return UIEdgeInsetsMake(150.0,0.0,150.0,0.0); // top, left, bottom, right
}
else{
return UIEdgeInsetsMake(20.0,0.0,0.0,0.0); // top, left, bottom, right
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
[m_coll performBatchUpdates:nil completion:nil];
}
-(void)viewWillTransitionToSize:withTransitionCoordinator{
[m_coll performBatchUpdates:nil completion:nil];
}
/*-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)
collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
CGFloat cellSpacing = ((UICollectionViewFlowLayout *) collectionViewLayout).minimumLineSpacing;
CGFloat cellWidth = ((UICollectionViewFlowLayout *) collectionViewLayout).itemSize.width;
NSInteger cellCount = [collectionView numberOfItemsInSection:section];
CGFloat inset = (collectionView.bounds.size.width - ((cellCount-1) * (cellWidth + cellSpacing))) * 0.5;
inset = MAX(inset, 0.0);
if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
NSLog(#"Changed to landscape Spacing");
return inset;
}
else{
return inset;
}
}*/
#end
Clear example to use custom collectionViewCell.
Create a separate class subclass ofUICollectionViewCell see below code:
.h file:
#import <UIKit/UIKit.h>
#interface CollectionViewCell : UICollectionViewCell
#property (weak, nonatomic) IBOutlet UILabel *customLabel;
#end
.m file:
#import "CollectionViewCell.h"
#implementation CollectionViewCell
#end
Now drag and drop the collectionView inside viewController using storyboard then by selecting cell set custom class for it and connect its IBOutlet of label see below image.
Setting up custom class:
Connecting label's outlet: if adding label and other ui component from storyboard
Note: Drag uilabel inside cell before you connect its IBOutlet.
Now configure cell inside your viewController class. And configure collectionView correctly by connecting its delegate, dataSuorce and IBOutlet.
#import "ViewController.h"
#import "CollectionViewCell.h"
#interface ViewController (){
// instance variable deceleration part
NSMutableArray *yourArray;
}
#end
#implementation ViewController
- (void)viewDidLoad{
[super viewDidLoad];
_yourCollView.delegate = self;
_yourCollView.dataSource = self;
yourArray = [[NSMutableArray alloc] initWithObjects:#"1st cell",#"2nd cell",#"3rd cell",#"4th cell", nil];
// Do any additional setup after loading the view, typically from a nib.
}
// collection view delegate methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [yourArray count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"MyCustomCell" forIndexPath:indexPath];
// configuring cell
// cell.customLabel.text = [yourArray objectAtIndex:indexPath.row]; // comment this line if you do not want add label from storyboard
// if you need to add label and other ui component programmatically
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height)];
label.tag = 200;
label.text = [yourArray objectAtIndex:indexPath.row];
// this adds the label inside cell
[cell.contentView addSubview:label];
return cell;
}
//Note: Above two "numberOfItemsInSection" & "cellForItemAtIndexPath" methods are required.
// this method overrides the changes you have made to inc or dec the size of cell using storyboard.
- (CGSize)collectionView:(UICollectionView *)collectionView layout: (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(100, 100);
}
} // class ends
Setup the cell identifier (by selecting a cell) MyCustomCell you have given inside cellForItemAtIndexPath method before use see below image:
Note: Change the text color of uilabel to white before because by default collectionView appears black.
Hope here you understand.
Create subclass of UICollectionViewCell. For instance TestCollectionViewCell.
In Storyboard drag label in cell and set "Custom class" for this UICollectionViewCell with your created class. Set Reusable identifier, if your collection view in UIViewController don't forget to set DataSource and Delegate for that collectionView.
Connect IBOutlet in your Cell subclass.
Set at least 1 value inside numberOfItemsInSection method.
Then use your subclass of cell in cellForItemAt and try set text for a label.
You are missing the:
[cell.contentView addSubview:issue];

UICollectionView not showing images from CameraImage - Objective C

Searched the forum and could not find a suitable answer that works. I suspect something is wrong with the code. I am taking pictures with a camera and trying to show them in a UICollectionView. The collectionView has a cell with a UIImageView inside of it.
Even when setting a static image and background colour I still don't see anything (not even the colour).
Code is as follows:
#import "CameraPageViewController.h"
#interface CameraPageViewController ()
#end
#implementation CameraPageViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
_imageList = [[NSMutableArray alloc] init];
_collectionView.delegate = self;
_collectionView.dataSource = self;
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"PictureCell"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)takePhoto:(id)sender {
UIImagePickerController *imagePickController=[[UIImagePickerController alloc]init];
imagePickController.sourceType=UIImagePickerControllerSourceTypeCamera;
imagePickController.delegate=self;
imagePickController.allowsEditing=TRUE;
[self presentViewController:imagePickController animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
UIImage *chosenImage = editingInfo[UIImagePickerControllerOriginalImage];
[_imageList addObject:chosenImage];
[self dismissViewControllerAnimated:YES completion:nil];
[_collectionView reloadData];
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self.imageList count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"PictureCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *pictureView = (UIImageView *) [cell viewWithTag:110];
NSInteger rowValue = indexPath.row;
UIImage *currentImage = [_imageList objectAtIndex:indexPath.row];
pictureView.image = currentImage;
return cell;
}
#end
i think u might missed the setting the layout for your collection view set it and try
- (void)viewDidLoad
{
[super viewDidLoad];
//...other code
_imageList = [[NSMutableArray alloc] init];
//set layout hear
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; //default layout
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
flowLayout.minimumInteritemSpacing = 0.0f;
flowLayout.minimumLineSpacing = 0.33f; //set the offset between items
_collectionView.showsHorizontalScrollIndicator = NO;
_collectionView.showsVerticalScrollIndicator = NO;
[_collectionView setCollectionViewLayout:flowLayout];
_collectionView.delegate = self;
_collectionView.dataSource = self;
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"PictureCell"];
}
//implement this delegate method to return item size for each cell
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(200.0f,300.0f);
}
Fixed it by adding the images as sub views through the code instead of the story board. No idea why it works, but it did.

How to display an image in a CustomView based on a TableView

I'm new to Cocoa/Objective-c so please bear with me on this.
I'm trying to create a simple program that has a TableView on the left of the window and a CustomView on the right. The TableView has 3 columns: (NSString) name, (NSInteger) x, (NSInteger) y. The x and y values are randomly generated between 0 and 100 whenever a new row is added. I have a simple Star class to hold these three attributes. The TableView seems to be working just fine.
On the right, I have a CustomView where I want to load an image whenever a new row is added to the tableview at the x,y for that entry.
I created this "addStar" method in the CustomView class, which is an NSView. Then, in my TableViewController class, I'm trying to call the "addStar" method in my "add" method that adds a new row.
When I launch the program, I'm able to add items to the TableView, but nothing shows up in the CustomView. Any ideas of where I'm going wrong here?
CustomView.m
#import "CustomView.h"
#implementation CustomView
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect
{
NSBezierPath* path = [NSBezierPath bezierPathWithRect:self.bounds];
[[NSColor whiteColor] setFill];
[path fill];
}
- (void)addStar:(float)x and:(float)y
{
NSRect rect = NSMakeRect(x, y, 35, 35);
imageView = [[NSImageView alloc] initWithFrame:rect];
[imageView setImageScaling:NSScaleNone];
[imageView setImage:[NSImage imageNamed:#"star.png"]];
[self addSubview:imageView];
}
#end
TableViewController.m
#import "TableViewController.h"
#import "CustomView.h"
#import "Star.h"
#implementation TableViewController
- (id)init
{
self = [super init];
if (self) {
list = [[NSMutableArray alloc] init];
}
return self;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [list count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
Star *s = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
return [s valueForKey:identifier];
}
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
Star *s = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
[s setValue:object forKey:identifier];
}
// Add row to the tableview
- (IBAction)add:(id)sender {
Star *star = [[Star alloc] init];
[list addObject:star];
[tableView reloadData];
// add star to the custom view
CustomView* cv = [[CustomView alloc] init];
[cv addStar:(float)[star xCoordinate] and:(float)[star yCoordinate]];
[star release];
}
- (IBAction)remove:(id)sender {
NSInteger row = [tableView selectedRow];
[tableView abortEditing];
if (row != -1)
[list removeObjectAtIndex:row];
[tableView reloadData];
}
- (void)dealloc
{
[list release];
[super dealloc];
}
#end
On right side you have Custom view And also you are creating new one as below...
CustomView* cv = [[CustomView alloc] init];
[cv addStar:(float)[star xCoordinate] and:(float)[star yCoordinate]];
But you are not adding this cv object on the screen.
write,
[self addSubview:cv];//add this below above code as you are creating new object each time.

Custom delegate/protocol didnt work like it should

I've been writing an app that has custom protocol to send the data from the child view to parent view the classes is
MainViewController
AddViewController (child to mainviewcontroller)
DaysViewController (child to addviewcontroller)
the custom protocol was declared in DaysViewController and implemented in AddViewController
AddViewController.h
#import <UIKit/UIKit.h>
#import "DaysViewController.h"
#import "Course.h"
#import "Student.h"
#interface AddViewController : UITableViewController<UIActionSheetDelegate,UIPickerViewDelegate,UIPickerViewDataSource,UIPickerViewAccessibilityDelegate,UITextFieldDelegate,DaysViewControllerDelegate>
{
NSArray *hoursarray;
UIActionSheet *aac;
IBOutlet UITextField *NameTx,*HoursTx,*DaysTx,*TimeTx;
Student *st;
Course *cc;
}
-(void) pickerDoneClick;
-(IBAction)fillTheOtherData;
#property (nonatomic ,strong) UIActionSheet *aac;
#end
AddViewController.m
#import "AddViewController.h"
#interface AddViewController ()
#end
#implementation AddViewController
#synthesize aac;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
//viewP.frame = CGRectMake(0, 154, 320, 205);
hoursarray = [[NSArray alloc]initWithObjects:#"2",#"3",#"4", nil];
[self.tableView setScrollEnabled:NO];
[DaysTx setEnabled:NO];
[TimeTx setEnabled:NO];
[HoursTx setKeyboardType:UIKeyboardTypeDecimalPad];
cc = [[Course alloc]init];
//UITapGestureRecognizer *tapgr = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapped:)];
//[self.view addGestureRecognizer:tapgr];
}
-(void)tapped:(UITapGestureRecognizer *)tap
{
[self.view endEditing:YES];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [hoursarray count];
}
//-(IBAction)addCourse
//{
// [UIView beginAnimations:#"view" context:nil];
// [UIView setAnimationDuration:1];
// viewP.frame = CGRectMake(0, 500, 320, 205);
// [UIView commitAnimations];
//
//}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [hoursarray objectAtIndex:row];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 3)
{
aac = [[UIActionSheet alloc]initWithTitle:#"How many ?" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil, nil];
UIPickerView *picker = [[UIPickerView alloc]initWithFrame:CGRectMake(0, 44, 0, 0)];
picker.delegate = self;
picker.dataSource = self;
UIToolbar *pickerToolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
[pickerToolBar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc]init];
UIBarButtonItem *flexspace = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexspace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDoneClick)];
[barItems addObject:doneBtn];
[pickerToolBar setItems:barItems animated:YES];
[aac addSubview:pickerToolBar];
[aac addSubview:picker];
[aac showInView:self.view];
[aac setBounds:CGRectMake(0, 0, 320, 464)];
}
else if (indexPath.row == 2)
{
DaysViewController *days = [self.storyboard instantiateViewControllerWithIdentifier:#"Days"];
days.delegate = self;
[self.navigationController pushViewController:days animated:YES];
}
}
-(void) pickerDoneClick
{
[aac dismissWithClickedButtonIndex:0 animated:YES];
}
-(void)chooseDays:(DaysViewController *)controller withArray:(NSArray *)theDaysArray
{
NSLog(#"I'm # chooseDays method");
NSLog(#"Before the add !!");
NSLog(#"chooseDays Method and the array is %#",theDaysArray);
cc.days = [NSMutableArray arrayWithObject:theDaysArray];
NSLog(#"After the add");
NSLog(#"chooseDays Method and the array is %#",cc.days);
// [self dismissViewControllerAnimated:YES completion:nil];
}
-(void)cancelChooseDays:(DaysViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
-(IBAction)fillTheOtherData
{
cc.name = NameTx.text;
cc.hour = [HoursTx.text integerValue];
NSLog(#"The name is %# and the hour credit is %d",cc.name,cc.hour);
}
#end
DaysViewController.h
#import <UIKit/UIKit.h>
#import "Course.h"
#class DaysViewController;
#protocol DaysViewControllerDelegate <NSObject>
#required
-(void)chooseDays:(DaysViewController *)controller withArray:(NSArray *)theDaysArray;
-(void)cancelChooseDays:(DaysViewController *)controller;
#end
#interface DaysViewController : UITableViewController
{
Course *courseDays;
NSArray *days;
NSMutableArray *dayChosen;
}
#property (nonatomic,weak) id<DaysViewControllerDelegate> delegate;
-(IBAction)done:(id)sender;
-(IBAction)cancel:(id)sender;
#end
DaysViewController.m
#import "DaysViewController.h"
#interface DaysViewController ()
#end
#implementation DaysViewController
#synthesize delegate;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
days = [[NSArray alloc]initWithObjects:#"Saturday",#"Sunday",#"Monday",#"Teusday",#"Wednesday",#"Thursday",#"Friday", nil];
dayChosen = [[NSMutableArray alloc]init];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [days count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"DaysCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"DaysCell"];
}
cell.textLabel.text = [days objectAtIndex:indexPath.row];
return cell;
}
-(IBAction)done:(id)sender
{
//Course *course = [[Course alloc]init];
//[course.days addObject:dayChosen];
//NSArray *daysArray = [NSArray arrayWithObject:dayChosen];
NSLog(#"The Days are %#",dayChosen);
[self.delegate chooseDays:self withArray:dayChosen];
[self dismissViewControllerAnimated:YES completion:nil];
}
-(IBAction)cancel:(id)sender
{
[self.delegate cancelChooseDays:self];
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[dayChosen addObject:[days objectAtIndex:indexPath.row]];
NSLog(#"Days are %#",dayChosen);
}
#end
MainViewController has a button that take me to AddViewController and AddViewController has same button that takes me to DaysViewController , all the views has a UITableView .
what I want to do is when I send the data from DaysViewController to AddViewController to put it in an array and dismiss the view AddViewController should show up but instead MainViewController shows and this is what I dont want it to be.
AddViewController and DaysViewController have a UINavigationController but MainViewController doesn't.
Thank you in advance.
Okay, I think I know what your problem is. In your cancel function, try and switch this line of code:
[self dismissViewControllerAnimated:YES completion:nil];
With this line of code:
[self.navigationController popViewControllerAnimated:YES];
Let me know if that helps.

UICollectionView Not Appearing

I am trying to set up UICollectionView programatically in my view controller which extends UIViewController. For some reason, my collection view is not showing up at all. Below is what I have.
Why is it not appearing? I am hooking it up to the delegate and data source and adding it as a subview to self.view. What's missing in my code?
In my .h file:
#interface MainViewController : UIViewController
{
#private
UICollectionView *_collectionView;
NSMutableArray *_results; // data source array
}
#end
In my .m file:
#interface MainViewController () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
#property (nonatomic, retain) UICollectionView *collectionView;
#property (nonatomic, retain) NSMutableArray *results;
#end
#implementation MainViewController
#synthesize collectionView = _collectionView;
#synthesize results = _results;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// some init stuff - nothing to do with collection view.
}
return self;
}
- (void)loadView
{
self.results = [NSMutableArray array];
UIImage *image1 = [UIImage imageNamed:#"img1.jpg"];
UIImage *image2 = [UIImage imageNamed:#"img2.jpg"];
[self.results addObject:image1];
[self.results addObject:image2];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) collectionViewLayout:flowLayout];
self.collectionView = collectionView;
[self.view addSubview:self.collectionView];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
[self.collectionView reloadData];
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section
{
return [self.results count];
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView
{
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor colorWithPatternImage:[self.results objectAtIndex:indexPath.row]];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
UIImage *image = [self.results objectAtIndex:indexPath.row];
return CGSizeMake(image.size.width, image.size.height);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(50, 20, 50, 20);
}
I got errors trying to run your code unless I changed the loadView method to viewDidLoad -- according to the docs you're not supposed to directly call loadView. To get the data source and delegate methods to run, I moved the lines setting the delegate and data source to self below where you set self.collectionView = collectionView
self.collectionView = collectionView;
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
Your numberOfSectionsInCollectionView: returns 0. For a collection view with one section, you should either return 1 or just not implement this method.
Also I cannot see where you alloc/init self.collectionView.
I ended up subclassing UICollectionViewController instead of UIViewController and changing the init method to:
- (id)initWithCollectionViewLayout:(UICollectionViewLayout *)layout
and it worked.
You only had to bind your CollectionView delegate, and dataSource to ViewController in the StoryBoard.enter image description here