UICollectionView Not Appearing - objective-c

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

Related

NSCollectionViewItems don't reload when scrolling <OSX - 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!

Derived UICollectionViewCell always returns null from dequeueReusableCellWithReuseIdentifier

I'm adding a UICollectionView programmatically to a controller, but no matter how I set it up, I can't get a valid UICollectionViewCell when calling dequeueReusableCellWithReuseIdentifier. Before showing the code, some info that might be helpful:
I'm using the latest XCode
I'm targeting iOS 8.1 on iPad
I'm not using a storyboard
I have a navigation controller setup and I'm also using Core Data
Here's the code:
Controller.h
#interface ViewController : UIViewController<UIImagePickerControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource>
#property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
#end
Controller.m
#interface ViewController ()
#property (strong, nonatomic) NSMutableArray *images;
#property (strong, nonatomic) UICollectionView *collectionView;
#end
// called by a button in the navigation bar
- (void)addMedia:(id)sender {
// load test images
if ([self.images count] == 0) {
NSBundle *myBundle = [NSBundle mainBundle];
NSArray *imagesPaths = [myBundle pathsForResourcesOfType:#"png" inDirectory:nil];
for (NSString *path in imagesPaths) {
UIImage *newImage = [[UIImage alloc] initWithContentsOfFile:path];
[self.images addObject:newImage];
}
self.introLabel.hidden = YES;
CGRect rect = CGRectMake(self.view.frame.size.width / 2 - 250,
self.view.frame.size.height / 2 - 250, 500, 500);
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(120, 120);
layout.minimumInteritemSpacing = 10;
self.collectionView = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:layout];
UINib *cellNib = [UINib nibWithNibName:#"ImageViewCell" bundle:nil];
[self. collectionView registerNib:cellNib forCellWithReuseIdentifier:#"imageCell"];
//[self.collectionView registerClass:[ImageViewCell class] forCellWithReuseIdentifier:#"imageCell"];
[self.collectionView setDelegate:self];
[self.collectionView setDataSource:self];
[self.view addSubview:self.collectionView];
}
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self.images count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// THIS IS ALWAYS NULL
ImageViewCell *cell = (ImageViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"imageCell" forIndexPath:indexPath];
cell.image.image = [self.images objectAtIndex:indexPath.row];
return cell;
}
ImageViewCell.h
#interface ImageViewCell : UICollectionViewCell
#property (strong, nonatomic) IBOutlet UIImageView *image;
#end
ImageViewCell.m
#implementation ImageViewCell
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
// THIS IS ALWAYS NULL!
return self;
}
#end
In the ImageViewCell.xib I have a UICollectionCellView as the main view, which contains the UIImageView I'm trying to populate; the UICollectionCellView points to ImageViewCell (the derived class).
I should mention that I tried the same approach with a new project with a single controller and adding programmatically the UICollectionView and it works, so I must be missing something silly or doing something slightly different but I'm not aware of it.
[EDIT]: changed the code with solution.
Make sure in the xib file that the File's Owner property indicates the class name that implements it. Then, implement:
- (NSString *)reuseIdentifier {
return #"imageCell";
}
in your ImageViewCell implementation. There also might be a way to set this in interface builder, rather than overriding the getter.
By the way, if your ImageViewCell is backed by a xib, initWithFrame: will not be the designated initializer, but instead initWithCoder will be. But your implementation is fine as is, and you don't necessarily need to override initWithCoder at this point.
EDIT: as rdelmar pointed out, you should definitely be using the registerNib version as well; you wouldn't need to implement the reuseIdentifier getter this way.

Detail View from TableView, Parsing

Can someone please help me, I looked everywhere to figure this out and nothing worked so far. I need to pass some data from table view to detail view and stick it into labels and Uiimage.
Data tableview is pulling comes from Parse database I created and seems to get pulled fine into the Tableview but I would like to use the same array that tableview is using for its data to fill out the detail view.
I am using 2 columns from parse to fill out this tableview Title and sub, and another tow columns to fill out the label and image. Here is my code so far. There is a bunch of variables that i was using in this code in DetailView
.h
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#interface BooksTableViewController : UITableViewController <UITableViewDelegate,NSObject >
{
NSArray * Booksarray;
}
#property (strong, nonatomic) IBOutlet UITableView *bookstableview;
#end
.m
#import "BooksTableViewController.h"
#import "BookDetailViewController.h"
#interface BooksTableViewController ()
#end
#implementation BooksTableViewController
#synthesize bookstableview;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(RetrieveDatafromParse)];
// 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;
}
-(void) RetrieveDatafromParse {
PFQuery * getbooks = [PFQuery queryWithClassName:#"BooksTableView"];
[getbooks findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(!error) {
Booksarray =[[NSArray alloc] initWithArray: objects];
}
[bookstableview reloadData];
NSLog(#"%#",objects);
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return Booksarray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * CellIdentifier = #"Cell";
UITableViewCell * cell = [bookstableview dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell ==nil) {
cell = [[ UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
PFObject * tempObject = [Booksarray objectAtIndex:indexPath.row];
cell.textLabel.text = [tempObject objectForKey:#"Books"];
cell.detailTextLabel.text= [tempObject objectForKey:#"Code"];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
BookDetailViewController * detailVC=[[BookDetailViewController alloc] initWithNibName:#"BookDetailViewController" bundle:nil];
detailVC.BookImage.image=[Booksarray objectAtIndex:indexPath.row];
detailVC.bookDesc.text=[Booksarray objectAtIndex:indexPath.row];
detailVC.bookTitle.text=[Booksarray objectAtIndex:indexPath.row];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.destinationViewController isKindOfClass: [BookDetailViewController class]]) {
BookDetailViewController *destination = segue.destinationViewController;
SEL selector = NSSelectorFromString(#"SetFile:");
if ([destination respondsToSelector:selector]) {
NSIndexPath *indexPath = [self.bookstableview indexPathForCell:sender];
PFObject * object = [Booksarray objectAtIndex:indexPath.row];
PFFile *file = [object objectForKey:#"BooksTableView"];
[destination setValue:file forKey:#"file"];
}
}
}
#end
.h
#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#interface BookDetailViewController : UIViewController <NSObject> {
}
#property (weak, nonatomic) IBOutlet UIImageView *BookImage;
#property (weak, nonatomic) IBOutlet UILabel *bookTitle;
#property (weak, nonatomic) IBOutlet UILabel *bookDesc;
#property (weak,nonatomic)PFFile *file;
#end
.m
#import "BookDetailViewController.h"
#import "BooksTableViewController.h"
#interface BookDetailViewController ()
#implementation BookDetailViewController
#synthesize BookImage,bookTitle,bookDesc,file,bookInfo,Picture,object2;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(RetrieveObjectsFromParse)];
self.bookTitle.text = [self.file objectForKey:#"Books"];
self.BookImage.image = [self.file objectForKey:#"BookImage"];
self.bookDesc.text =[self.file objectForKey:#"BookDetails"];
}
-(void)RetrieveObjectsFromParse {
PFQuery * GetObjects = [PFQuery queryWithClassName:#"BooksTableView"];
[GetObjects findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if(!error) {
details =[[NSArray alloc] initWithArray: objects];
};
NSLog(#"%#",objects);
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
Try this:
#1 create a segue from controller to controller:
#2 Give your segue an Id for example detailSegue.
#3 Perform the segue in didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"detailSegue" sender:sender];
}
#4 Implement the segue delegate:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if([segue.identifier isEqualToString:#"detailSegue"]){
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
BookDetailViewController *detailVC = (BookDetailViewController *)segue.destinationViewController;
detailVC.bookDesc.text=[Booksarray objectAtIndex:indexPath.row];
//I uncommented that because it looks like a typo, same value 3 times?
//detailVC.BookImage.image=[Booksarray objectAtIndex:indexPath.row];
//detailVC.bookTitle.text=[Booksarray objectAtIndex:indexPath.row];
}
}
If this is the log you get:
2014-03-21 15:06:20.151 BookStore[25539:90b]
BookIndex= { BookDetails = "Test
test"; BookImage = ""; Books = Languages; Code =
104; }
Then you need to do it like this instead:
detailVC.bookTitle.text=[[Booksarray objectAtIndex:indexPath.row]objectForKey:#"Books"];
detailVC.bookDesc.text= [[Booksarray objectAtIndex:indexPath.row]objectForKey:#"BookDetails"];
detailVC.BookImage.image=[[Booksarray objectAtIndex:indexPath.row]objectForKey:#"BookImage"];
Or to make it shorter:
NSArray *bookAtIndex = [Booksarray objectAtIndex:indexPath.row];
detailVC.bookTitle.text=[bookAtIndex objectForKey:#"Books"];
detailVC.bookDesc.text= [bookAtIndex objectForKey:#"BookDetails"];
detailVC.BookImage.image=[bookAtIndex objectForKey:#"BookImage"];
or even shorter
NSArray *bookAtIndex = Booksarray[indexPath.row];
detailVC.bookTitle.text= bookAtIndex[#"Books"];
detailVC.bookDesc.text= bookAtIndex[#"BookDetails"];
detailVC.BookImage.image= bookAtIndex[#"BookImage"];

Master - detail tableviews - not sure about how/where to do the IF-statement

In my app I´m using a master tableView with 3 cells, taken from a JSON. Each of these 3 cells will be connected to another tableView but Im not sure how to do this IF-statement.
Heres the .m for the master tableView. So far I only connected 1 detailView(tableView) to the master:
#import "GuideTableViewController.h"
#import "GuideDetailTableViewController.h"
#import <QuartzCore/QuartzCore.h>
#interface GuideTableViewController (){
NSArray *guide;
}
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#property (weak, nonatomic) IBOutlet UIImageView *imgHeader;
#property (weak, nonatomic) IBOutlet UIButton *btnMap;
#property (weak, nonatomic) IBOutlet UIImageView *ImgTitle;
#end
#implementation GuideTableViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
//JSONmetod
- (void) loadJSON{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//code
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"https://dl.dropbox.com/u/100670549/test.json"]];
NSError *error;
if (data)
{
guide = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
for (NSDictionary *dictionary in guide){
NSLog([dictionary description]);
}
}else
{
NSLog(#"Could not load data");
}
dispatch_sync(dispatch_get_main_queue(), ^{
// code
[self.tableView reloadData];
});
});
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Anropa json
[self loadJSON];
//set background
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.jpg"]];
//rounded corners
[self.tableView.layer setCornerRadius:9.0];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//TableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 3;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
NSDictionary *dict = [guide objectAtIndex:indexPath.row];
cell.textLabel.text = [dict valueForKey:#"title"];
return cell;
}
//To detailView. Started with an IF here.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showStay"]){
GuideDetailTableViewController *tvc = [segue destinationViewController];
NSIndexPath *index = sender;
NSDictionary *dict = [guide objectAtIndex:index.row];
tvc.stay = dict;
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self performSegueWithIdentifier:#"showStay" sender:indexPath];
}
- (void) viewWillAppear:(BOOL)animated{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.tableView.indexPathForSelectedRow];
//ta bort markeringen när man går tillbaka till master från detailView.
[cell setSelected:NO];
//Hide navbar
[self.navigationController setNavigationBarHidden:YES];
}
//Show navbar in detailView
-(void)viewWillDisappear:(BOOL)animated{
[self.navigationController setNavigationBarHidden:NO];
}
#end
Thanks in advance!
Your code is all right.
The if-statement is at the right place.
If you already linked your prototype cell to the detail view in the storyboard you don't need to implement tableView:DidSelectRowAtIndexPath:
prepareForSegue:sender: is called automaticaly.

IOS 5.1 ARC Unrecognized Selector Sent to Instance

I have been looking at similar question but couldn't figure it out what is the problem.It seems it should work but it gives me error.
In IOS 5.1 Ipad Stortyboard application I have a right navigation bar item when user click a popover view should open. I had a working popover view but design was not good so I replaced it with a new popover class now it gives me following error
-[UIButton view]: unrecognized selector sent to instance 0xa17ba80
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIButton view]: unrecognized selector sent to instance 0xa17ba80'
I have tried following functions but none has worked so far. It gives me similar errors when I change the code.
- (IBAction)setColorButtonTapped:(id)sender{
- (void)setColorButtonTapped:(id)sender{
- (IBAction)setColorButtonTapped:(id)sender forEvent:(UIEvent*)event {
- (void)setColorButtonTapped:(id)sender forEvent:(UIEvent*)event {
and ofcourse I have changed ti following regarding to ibaction or void
[backButton2 addTarget:self action:#selector(setColorButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
here is the code
my.h file
#import <UIKit/UIKit.h>
#import "ColorPickerController.h"
#interface MeetingViewController : UITableViewController<UIApplicationDelegate,UIAlertViewDelegate,DropDownListDelegate,MFMailComposeViewControllerDelegate,EGORefreshTableHeaderDelegate,ColorPickerDelegate>{
UIPopoverController *_popover;
ColorPickerController *_colorPicker;
UIPopoverController *_colorPickerPopover;
}
#property (nonatomic, strong) UIPopoverController *popover;
#property (nonatomic, strong) ColorPickerController *colorPicker;
#property (nonatomic, strong) UIPopoverController *colorPickerPopover;
- (IBAction)setColorButtonTapped:(id)sender;
#end
my.m file
#synthesize popover = _popover;
#synthesize colorPicker = _colorPicker;
#synthesize colorPickerPopover = _colorPickerPopover;
- (void)viewDidLoad
{
[super viewDidLoad];
//gear button on navigation Bar
UIImage* imageback2 = [UIImage imageNamed:#"ICON - Gear#2x.png"];
CGRect frameimgback2 = CGRectMake(0, 0, 40, 40);
UIButton *backButton2 = [[UIButton alloc] initWithFrame:frameimgback2];
[backButton2 setBackgroundImage:imageback2 forState:UIControlStateNormal];
[backButton2 addTarget:self
action:#selector(setColorButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *btn2 = [[UIBarButtonItem alloc] initWithCustomView:backButton2];
self.navigationItem.rightBarButtonItem = btn2;
}
#pragma mark ColorPickerDelegate
- (void)colorSelected:(NSString *)color {
[self.colorPickerPopover dismissPopoverAnimated:YES];
}
#pragma mark Callbacks
- (IBAction)setColorButtonTapped:(id)sender {
if (_colorPicker == nil) {
self.colorPicker = [[ColorPickerController alloc] initWithStyle:UITableViewStylePlain];
_colorPicker.delegate = self;
self.colorPickerPopover = [[UIPopoverController alloc] initWithContentViewController:_colorPicker];
}
[self.colorPickerPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
utility class
ColorPickerController.h
#import <UIKit/UIKit.h>
#protocol ColorPickerDelegate
- (void)colorSelected:(NSString *)color;
#end
#interface ColorPickerController : UITableViewController {
NSMutableArray *_colors;
id<ColorPickerDelegate> __weak _delegate;
}
#property (nonatomic, strong) NSMutableArray *colors;
#property (nonatomic, weak) id<ColorPickerDelegate> delegate;
#end
utilityclass
ColorPickerController.m
#import "ColorPickerController.h"
#implementation ColorPickerController
#synthesize colors = _colors;
#synthesize delegate = _delegate;
#pragma mark -
#pragma mark Initialization
/*
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
if ((self = [super initWithStyle:style])) {
}
return self;
}
*/
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.clearsSelectionOnViewWillAppear = NO;
self.contentSizeForViewInPopover = CGSizeMake(150.0, 140.0);
self.colors = [NSMutableArray array];
[_colors addObject:#"Red"];
[_colors addObject:#"Green"];
[_colors addObject:#"Blue"];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Override to allow orientations other than the default portrait orientation.
return YES;
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [_colors count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSString *color = [_colors objectAtIndex:indexPath.row];
cell.textLabel.text = color;
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (_delegate != nil) {
NSString *color = [_colors objectAtIndex:indexPath.row];
[_delegate colorSelected:color];
}
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
self.delegate = nil;
}
#end
Help is much appreciated , thanks
You're using a UIButton as a customView for a UIBarButtonItem. This could be the problem.
I suggest you use UIBarButtonItem's initWithImage:style:target:action: initializer instead.
UIButton is a view and as such has no view property or instance method.