Again the Unbalanced calls to begin/end appearance transitions - objective-c

I know the question has already been asked and answered but I cant find the solution.
I've got this error even if I'm not pushing the incriminated view controller :
Unbalanced calls to begin/end appearance transitions for .
here is my code NewsViewController.m
#import "NewsViewController.h"
#import "XMLToObjectParser.h"
#import "UneNews.h"
#define USE_CUSTOM_DRAWING 1
#interface NewsViewController ()
#end
#implementation NewsViewController
#synthesize imageView;
#synthesize vueDetail;
#synthesize tableauNews,tableViewFluxRSS;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil tableauDeNews:(NSMutableArray *)tableauDeNews
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
//récupération du tableau de news initialisé
tableauNews = tableauDeNews;
}
return self;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
tableViewFluxRSS.separatorStyle = UITableViewCellSeparatorStyleNone;
tableViewFluxRSS.rowHeight = 143;
tableViewFluxRSS.backgroundColor = [UIColor clearColor];
}
- (void)viewDidUnload
{
[self setImageView:nil];
[self setVueDetail:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return NO;
}
//Navigation
- (IBAction)goHome:(id)sender{
[self.navigationController popToRootViewControllerAnimated:YES];
}
// Override to support row selection in the table view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here -- for example, create and push another view controller.
[vueDetail loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[[tableauNews objectAtIndex:indexPath.row] detail]]]];
}
//gestion du UITableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [tableauNews count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
const NSInteger TOP_LABEL_TAG = 1001;
const NSInteger BOTTOM_LABEL_TAG = 1002;
const NSInteger DATE_LABEL_TAG = 1003;
const NSInteger ANNEE_LABEL_TAG = 1004;
UILabel *topLabel;
UILabel *bottomLabel;
UILabel *dateLabel;
UILabel *anneeLabel;
UILabel *enSavoirPlus;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableViewFluxRSS dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//
// Create the cell.
//
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
//
// Configure the properties for the text that are the same on every row
//
dateLabel = [[UILabel alloc]
initWithFrame:
CGRectMake(6,46,75,57)];
dateLabel.tag = DATE_LABEL_TAG;
dateLabel.backgroundColor = [UIColor clearColor];
dateLabel.textColor = [UIColor whiteColor];
dateLabel.font = [UIFont systemFontOfSize:28];
[cell.contentView addSubview:dateLabel];
//
// Configure the properties for the text that are the same on every row
//
anneeLabel = [[UILabel alloc]
initWithFrame:
CGRectMake(6,100,70,57)];
anneeLabel.tag = DATE_LABEL_TAG;
anneeLabel.backgroundColor = [UIColor clearColor];
anneeLabel.textColor = [UIColor whiteColor];
anneeLabel.font = [UIFont systemFontOfSize:31];
[cell.contentView addSubview:anneeLabel];
topLabel =
[[UILabel alloc]
initWithFrame:
CGRectMake(94,5,325,20)];
[cell.contentView addSubview:topLabel];
//
// Configure the properties for the text that are the same on every row
//
topLabel.tag = TOP_LABEL_TAG;
topLabel.backgroundColor = [UIColor clearColor];
topLabel.textColor = [UIColor whiteColor];
topLabel.font = [UIFont systemFontOfSize:18];
//
// Configure the properties for the text that are the same on every row
//
bottomLabel =
[[UILabel alloc]
initWithFrame:
CGRectMake(94,30,325,80)];
bottomLabel.tag = BOTTOM_LABEL_TAG;
bottomLabel.backgroundColor = [UIColor clearColor];
bottomLabel.textColor = [UIColor whiteColor];
bottomLabel.font = [UIFont systemFontOfSize:18];
[bottomLabel setLineBreakMode:UILineBreakModeWordWrap];
[bottomLabel setNumberOfLines:0];
[cell.contentView addSubview:bottomLabel];
//
// Create a background image view.
//
cell.backgroundView =
[[UIImageView alloc] init];
cell.selectedBackgroundView =
[[UIImageView alloc] init];
enSavoirPlus =
[[UILabel alloc]
initWithFrame:
CGRectMake(260,121,200,20)];
[cell.contentView addSubview:enSavoirPlus];
//
// Configure the properties for the text that are the same on every row
//
enSavoirPlus.tag = TOP_LABEL_TAG;
enSavoirPlus.backgroundColor = [UIColor clearColor];
enSavoirPlus.textColor = [UIColor yellowColor];
//topLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
enSavoirPlus.font = [UIFont systemFontOfSize:18];
}
else
{
topLabel = (UILabel *)[cell viewWithTag:TOP_LABEL_TAG];
bottomLabel = (UILabel *)[cell viewWithTag:BOTTOM_LABEL_TAG];
dateLabel = (UILabel *)[cell viewWithTag:DATE_LABEL_TAG];
anneeLabel = (UILabel *)[cell viewWithTag:ANNEE_LABEL_TAG];
}
topLabel.text = [[tableauNews objectAtIndex:indexPath.row] titre];
bottomLabel.text = [[tableauNews objectAtIndex:indexPath.row] contenu];
[bottomLabel sizeToFit];
dateLabel.text = [[tableauNews objectAtIndex:indexPath.row] dateDeParution];
anneeLabel.text = [[tableauNews objectAtIndex:indexPath.row] annee];
enSavoirPlus.text = #"En savoir plus...";
//
// Set the background and selected background images for the text.
// Since we will round the corners at the top and bottom of sections, we
// need to conditionally choose the images based on the row index and the
// number of rows in the section.
//
UIImage *rowBackground;
rowBackground = [UIImage imageNamed:#"fd-textes-news.png"];
//selectionBackground = [UIImage imageNamed:#"middleRowSelected.png"];
((UIImageView *)cell.backgroundView).image = rowBackground;
//((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;
return cell;
}
//fin gestion UITableView
#end
I think my problem may be due to my implementation of the init
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil tableauDeNews:(NSMutableArray *)tableauDeNews;
need help
thx

I found the problem:
To create my buttons I copy paste them in the interfaceBuilder,
the copied buttons have kept their old actions, and I had a new IBAction.
My copied buttons had 2 IBactions (one calling a NewsViewController and another calling the right viewController).
The message was poping each time I clicked the copied button.
So check your buttons in the interface Builder, "Unbalanced calls to begin/end appearance transitions" can be caused by buttons having two IBActions, conflictual (eg. pushing two different viewControllers at the same time).

Related

Avoiding UICollectionViewCell re-selection during reuse (from cell's prepareForResue) 'apparently' deselects the original cell as well

In my collection view when (custom) cells are reused they, again, get the highlight I have set in didSelectItemAtIndexPath for the original selection. To prevent this, I am using the custom cell's prepareForReuse method, and post calling [super], I check to see if its the selected cell.
If it is I am change the highlight to default else I restore to the original selection highlight when the cell in question is brought back in scroll view's visible area.
Here's the code...
- (void)prepareForReuse
{
[super prepareForReuse];
if (!self.isSelected) {
[self setBackgroundColor:[UIColor systemBackgroundColor]];
[_tagImageView setTintColor:[UIColor systemBlueColor]];
}
else if (self.isSelected)
{
[self setBackgroundColor:[UIColor systemBlueColor]];
[_tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
}
But I notice that the second if block is never executed even when I bring back the original cell in view. This is where I need help. How do I ensure re-highlighting or the original cell/item?
Note, if I try and save the original cell- even though not highlighted, remains the one selected and the corresponding value is saved.
So, this is just about the re-highlight.
Also, here is the selection code...* didSelectItemAtIndexPath*
- (void)collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (selectedIndexPath!=nil) {
if (indexPath.row==selectedIndexPath.row)
{
[tagCollectionView deselectItemAtIndexPath:indexPath animated:YES];
TagCollectionViewCell *selectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
selectedCell.backgroundColor = [UIColor clearColor];
selectedCell.tagImageView.tintColor = [UIColor systemBlueColor];
selectedIndexPath=nil;
[newDictionary setValue:[NSNull null] forKey:#"type"];
}
else
{
[tagCollectionView deselectItemAtIndexPath:indexPath animated:YES];
TagCollectionViewCell *previousSelectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
previousSelectedCell.backgroundColor = [UIColor systemBackgroundColor];
previousSelectedCell.tagImageView.tintColor = [UIColor systemBlueColor];
selectedIndexPath = indexPath;
TagCollectionViewCell *selectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
selectedCell.backgroundColor = [UIColor systemBlueColor];
selectedCell.tagImageView.tintColor = [UIColor systemBackgroundColor];
dictionaryType = _typesArray[selectedIndexPath.row];
[newDictionary setValue:dictionaryType forKey:#"type"];
}
}
else if (selectedIndexPath==nil)
{
selectedIndexPath = indexPath;
TagCollectionViewCell *selectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
selectedCell.backgroundColor = [UIColor systemBlueColor];
selectedCell.tagImageView.tintColor = [UIColor systemBackgroundColor];
dictionaryType = _typesArray[selectedIndexPath.row];
[newDictionary setValue:dictionaryType forKey:#"type"];
}
}
Any help? Thanks.
Edit:
This is the part of the code that doesn't get called.
else if (self.isSelected)
{
[self setBackgroundColor:[UIColor systemBlueColor]];
[_tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
I think you are way over-complicating things.
A UICollectionView keeps track of its own "selected" cell(s), and calls setSelected on each cell when it is displayed.
You can put all of your "selected" appearance code inside your cell class:
- (void)setSelected:(BOOL)selected {
// change our color properties based on selected BOOL value
self.tagImageView.tintColor = selected ? UIColor.systemBackgroundColor : UIColor.systemBlueColor;
self.backgroundColor = selected ? UIColor.systemBlueColor : UIColor.systemBackgroundColor;
}
Now you don't need to do anything in didSelectItemAt.
Here's a quick example...
SampleCollectionViewCell.h
#interface SampleCollectionViewCell : UICollectionViewCell
- (void)fillData:(NSInteger)n;
#end
SampleCollectionViewCell.m
#import "SampleCollectionViewCell.h"
#interface SampleCollectionViewCell ()
{
UIImageView *theImageView;
UILabel *theLabel;
}
#end
#implementation SampleCollectionViewCell
- (instancetype)init
{
self = [super init];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit {
// add an image view and a label
theImageView = [UIImageView new];
theImageView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:theImageView];
theLabel = [UILabel new];
theLabel.textAlignment = NSTextAlignmentCenter;
theLabel.font = [UIFont systemFontOfSize:20.0 weight:UIFontWeightBold];
theLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:theLabel];
[NSLayoutConstraint activateConstraints:#[
[theImageView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:0.0],
[theImageView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:0.0],
[theImageView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:0.0],
[theImageView.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:0.0],
[theLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:0.0],
[theLabel.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:0.0],
[theLabel.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-4.0],
]];
// image would probably be set by the data source, but
// for this example we'll use the same system image in every cell
UIImage *img = [UIImage systemImageNamed:#"person.fill"];
if (img) {
theImageView.image = img;
}
// let's give the content view rounded corners and a border
self.contentView.layer.cornerRadius = 8.0;
self.contentView.layer.borderWidth = 2.0;
self.contentView.layer.borderColor = UIColor.systemGreenColor.CGColor;
// default (not-selected) colors
theImageView.tintColor = UIColor.cyanColor;
theLabel.textColor = UIColor.blackColor;
self.contentView.backgroundColor = UIColor.systemBackgroundColor;
}
- (void)fillData:(NSInteger)n {
theLabel.text = [NSString stringWithFormat:#"%ld", (long)n];
}
- (void)setSelected:(BOOL)selected {
// change our color properties based on selected BOOL value
theImageView.tintColor = selected ? UIColor.redColor : UIColor.cyanColor;
theLabel.textColor = selected ? UIColor.yellowColor : UIColor.blackColor;
self.contentView.backgroundColor = selected ? UIColor.systemBlueColor : UIColor.systemBackgroundColor;
}
#end
SampleViewController.h
#interface SampleViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource>
#end
SampleViewController.m
#import "SampleViewController.h"
#import "SampleCollectionViewCell.h"
#interface SampleViewController ()
{
UICollectionView *collectionView;
}
#end
#implementation SampleViewController
- (void)viewDidLoad {
[super viewDidLoad];
UICollectionViewFlowLayout *fl = [UICollectionViewFlowLayout new];
fl.scrollDirection = UICollectionViewScrollDirectionVertical;
fl.itemSize = CGSizeMake(60, 60);
fl.minimumLineSpacing = 8;
fl.minimumInteritemSpacing = 8;
collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:fl];
collectionView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:collectionView];
UILayoutGuide *g = [self.view safeAreaLayoutGuide];
[NSLayoutConstraint activateConstraints:#[
// constrain collection view 40-points from all 4 sides
[collectionView.topAnchor constraintEqualToAnchor:g.topAnchor constant:40.0],
[collectionView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:40.0],
[collectionView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-40.0],
[collectionView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-40.0],
]];
[collectionView registerClass:SampleCollectionViewCell.class forCellWithReuseIdentifier:#"c"];
collectionView.dataSource = self;
collectionView.delegate = self;
// let's give the collection view a very light gray background
// so we can see its frame
collectionView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 50;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
SampleCollectionViewCell *c = (SampleCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"c" forIndexPath:indexPath];
[c fillData:indexPath.item];
return c;
}
#end
Based on the code you posted, it looks like you want to be able to de-select an already selected cell. If so, add this to the controller:
// this allows us to de-select an already selected cell
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
// get array of already selected index paths
NSArray *a = [collectionView indexPathsForSelectedItems];
// if that array contains indexPath, that means
// it is already selected, so
if ([a containsObject:indexPath]) {
// deselect it
[collectionView deselectItemAtIndexPath:indexPath animated:NO];
return NO;
}
// no indexPaths (cells) were selected
return YES;
}
When run, it starts like this:
Tapping cell "1" selects it:
Tapping cell "7" automatically de-selects cell "1" and selects cell "7":
We can scroll up and down and the selected cell will automatically maintain its "selected appearance":
Edit
To explain why your prepareForReuse wasn't doing what you expected...
The collection view does not set the selected property of the cell until it is going to be displayed.
So, in:
- (void)prepareForReuse
{
[super prepareForReuse];
if (!self.isSelected) {
[self setBackgroundColor:[UIColor systemBackgroundColor]];
[_tagImageView setTintColor:[UIColor systemBlueColor]];
}
else if (self.isSelected)
{
[self setBackgroundColor:[UIColor systemBlueColor]];
[_tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
}
self.isSelected will never be true.
If you want to stick with changing the cell UI properties (colors, tint, etc) in didSelectItemAt, you need to update your cell appearance in cellForItemAt:
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
TagCollectionViewCell *c = (TagCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"c" forIndexPath:indexPath];
// whatever you are currently doing, such as
//c.tagImageView.image = ...;
if (selectedIndexPath != indexPath) {
[c setBackgroundColor:[UIColor systemBackgroundColor]];
[c.tagImageView setTintColor:[UIColor systemBlueColor]];
}
else
{
[c setBackgroundColor:[UIColor systemBlueColor]];
[c.tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
return c;
}

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 didn't render properly

The program has a tableview. Each TableViewCell has a UICollectionView. When user drag and drop the one of the categories label, the program will add a UICollectionViewCell which has a UIView. It works well. However, when user scroll the tableview then the UICollectionView won't render properly. The display is as below.
This is the pic before user scroll the view.
http://cl.ly/image/1P0s3Z0m443t
After user scroll the view, there is a promise overlap the sin. The promise cell shouldn't be there.
http://cl.ly/image/3L2M1s3s3F0X
Here is my code of cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
// Configure the cell..
/*
There is no UITableViewCell in the storyboard
*/
ContentViewCustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel * cellLabel = nil; //The cellLabel is for rendering the bible verses
if (cell==nil) {
cell = [[ContentViewCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
/*
To Make Dynamic Cell Height
*/
cellLabel = [[UILabel alloc] initWithFrame:CGRectZero];
[cellLabel setNumberOfLines:0];
[cellLabel sizeToFit];
[cellLabel setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[cellLabel setTag:1];
[[cell contentView] addSubview:cellLabel];
}
NSString * text = [verseArray objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGRect rectangular = [text boundingRectWithSize:constraint options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName: [UIFont systemFontOfSize:FONT_SIZE]} context:nil];
CGSize size = rectangular.size;
/*
When There Are Rows More Than One Screen
*/
if (!cellLabel) {
cellLabel = (UILabel *)[cell viewWithTag:1];
}
cell.CellContent = text;
[cellLabel setText:text];
[cellLabel setFrame:CGRectMake((self.view.frame.size.width*0.39), 0, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))]; //To Locate The Position Of The Label In The Cell
cell.userInteractionEnabled = TRUE;
return cell;
}
And this is ContentViewCustomTableViewCell
#import "ContentViewCustomTableViewCell.h"
#import "AnswerCollectionViewCell.h"
#implementation ContentViewCustomTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(3, 3, 2, 2);
layout.itemSize = CGSizeMake(30, 10);
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
self.collectionView = [[AFIndexedCollectionView alloc] initWithFrame:CGRectZero
collectionViewLayout:layout];
[self.collectionView registerClass:[AnswerCollectionViewCell class]forCellWithReuseIdentifier:CollectionViewCellIdentifier];
self.collectionView.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:0.1];
self.collectionView.showsVerticalScrollIndicator = NO;
[self.contentView addSubview:self.collectionView];
}
return self;
}
- (void)awakeFromNib
{
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void)layoutSubviews
{
[super layoutSubviews];
self.collectionView.frame = CGRectMake(10, 10, 110, 50);
}
-(void)setCollectionViewDataSourceDelegate:(id<UICollectionViewDataSource, UICollectionViewDelegate>)dataSourceDelegate index:(NSInteger)index
{
self.collectionView.dataSource = dataSourceDelegate;
self.collectionView.delegate = dataSourceDelegate;
self.collectionView.index = index;
[self.collectionView reloadData];
}
#end

Unable to set the frame of UITableViewCell's contentView

Im trying to set an offset of the contentView of my UITableViewCell. But failed. As you can find in the picture, there is no offset.
The corresponding code is as following.
MyCell.m
#import "MyCell.h"
#implementation MyCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
UIView *backGroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
[backGroundView setBackgroundColor:[UIColor grayColor]];
[self addSubview:backGroundView];
UIView *frontView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
[frontView setBackgroundColor:[UIColor greenColor]];
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
myLabel.text = #"My Cell";
myLabel.backgroundColor = [UIColor clearColor];
[myLabel setTextAlignment:UITextAlignmentCenter];
[frontView addSubview:myLabel];
[self.contentView addSubview:frontView];
[self bringSubviewToFront:self.contentView];
}
return self;
}
MyTableViewController.m
#import "MyTableViewController.h"
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MyCell";
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
CGPoint center = cell.center;
center.x = cell.contentView.bounds.size.width/2 - 20;
[cell.contentView setCenter:center];
NSLog(#"origin.x :%f ,y :%f, width :%f, height :%f",cell.contentView.frame.origin.x, cell.contentView.frame.origin.y, cell.contentView.frame.size.width,cell.contentView.frame.size.height);
return cell;
}
log
2012-08-31 18:29:34.075 TableViewCellOffsetTest[16169:207] origin.x :-20.000000 ,y :0.000000, width :320.000000, height :44.000000
Show us your code relating to [cell.contentView setCenter:center]; I suspect you're trying to move the main view of the cell. I wouldn't do that I would add a subview and offset that and add your content views to it. As you're already using a custom method all your changes need to be made there. In addition it's worth noting that you would also want to reset the cells offset each time it's reused as you'll end up moving the content further and further along.

AQGridViewCell customization

I am looking to customize an AQGridViewCell by adding a title, date, and image for each cell.
What I have tried so far is:
//View Controller
- (AQGridViewCell *) gridView: (AQGridView *) gridView cellForItemAtIndex: (NSUInteger) index
{
static NSString * CellIdentifier = #"CellIdentifier";
IssueCell * cell = (IssueCell *)[self.gridView dequeueReusableCellWithIdentifier: CellIdentifier];
if ( cell == nil )
{
cell = [[IssueCell alloc] initWithFrame: CGRectMake(0.0, 0.0, 72.0, 72.0) reuseIdentifier: CellIdentifier];
}
//This model object contains the title, picture, and date information
IssueModel *m = (IssueModel *)[self.issues objectAtIndex:index];
[cell setIssueModel:m];
return cell;
}
//Cell class
#import "IssueCell.h"
#import <QuartzCore/QuartzCore.h>
#implementation IssueCell
#synthesize issueModel;
- (id) initWithFrame: (CGRect) frame reuseIdentifier:(NSString *) reuseIdentifier
{
self = [super initWithFrame: frame reuseIdentifier: reuseIdentifier];
if ( self == nil )
return ( nil );
self.contentView.backgroundColor = [UIColor redColor];
self.backgroundColor = [UIColor blueColor];
self.contentView.opaque = NO;
self.opaque = NO;
self.selectionStyle = AQGridViewCellSelectionStyleNone;
return self;
}
#end
My questions is, since init is called before I have access to the model object, where can I setup the title, picture, and date for my cell?
You have to initialize your UI components in the initWithFrame. Example:
In the interface of your IssueCell add UI variables you would like to have:
#interface IssueCell : AQGridViewCell {
UIImageView *im;
UILabel *dateLabel;
}
- (id) initWithFrame: (CGRect) frame reuseIdentifier:(NSString *) reuseIdentifier
{
self = [super initWithFrame: frame reuseIdentifier: reuseIdentifier];
if ( self == nil )
return ( nil );
self.contentView.backgroundColor = [UIColor redColor];
self.backgroundColor = [UIColor blueColor];
self.contentView.opaque = NO;
self.opaque = NO;
self.selectionStyle = AQGridViewCellSelectionStyleNone;
im = [[UIImageView alloc] initWithFrame:yourImageViewFrameHere];
dateLabel = [[UILabel alloc] initWithFrame:yourLabelFrameHere];
[self addSubview:im];
[self addSubview:dateLabel];
return self;
}
#end
Later, you assign desired values in the cellForItemAtIndex method. Example:
- (AQGridViewCell *) gridView: (AQGridView *) gridView cellForItemAtIndex: (NSUInteger) index
{
static NSString * CellIdentifier = #"CellIdentifier";
IssueCell * cell = (IssueCell *)[self.gridView dequeueReusableCellWithIdentifier: CellIdentifier];
if ( cell == nil )
{
cell = [[IssueCell alloc] initWithFrame: CGRectMake(0.0, 0.0, 72.0, 72.0) reuseIdentifier: CellIdentifier];
}
//This model object contains the title, picture, and date information
//
IssueModel *m = (IssueModel *)[self.issues objectAtIndex:index];
[cell.im setImage: m.picture];
[cell.dateLabel setText:[date localizedDescription]];
return cell;
}
Do not store your model data in the UI components. That's a no no. Keep your model separated from the UI. This is only a pseudocode, not tested since I do not have my mac here.
Let me know if it helps.