Overlay a static UIButton onto a UICollectionView - ios

I have a UICollectionView that has an array of UICollectionViewCell each cell takes up 80% of the view.
I want to add a static UIButton onto the screen that scrolls to the next cell every time it is pressed, I will have to add the button subview onto the Parent view and not the UICollectionView for it to be static.
My questions are : how do I add the overlay onto the main view and how do I scroll the view programmatically with the press of the button?
Where I implemented my collection view
#interface EvaluationViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
#property (weak, nonatomic) IBOutlet UIBarButtonItem *cancelButton;
#property (nonatomic, strong) DBManager* dbManager;
#end
#implementation EvaluationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.dbManager = [[DBManager alloc] initWithDatabaseFilename:#"emokitDb.sqlite"];
NSLog(#"self.dbManager %#",self.dbManager.documentsDirectory);
[self loadProjectWithId:1];
}
- (IBAction)cancelButton:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 4;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Screen * screen = [self.project.screens objectAtIndex:indexPath.row];
static NSString * cellIdentifier = #"EvaluationCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
return cell;
}
-(void)loadProjectWithId:(int)projectId {
}
#end

It is quite easy:
You can add the button like that:
And you have to give a target to the button to move collectionView contentOffset...
- (void)viewDidLoad
{
[super viewDidLoad];
self.dbManager = [[DBManager alloc] initWithDatabaseFilename:#"emokitDb.sqlite"];
NSLog(#"self.dbManager %#",self.dbManager.documentsDirectory);
[self loadProjectWithId:1];
UIButton * button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(910, 400 , 100, 100);
button.backgroundColor =[UIColor blackColor];
[self.collectionView.superview addSubview:button];
[button addTarget:self action:#selector(changeContentOffset:) forControlEvents:UIControlEventTouchUpInside];
}
Then in the selector you have to implement a method to change contentOffset
- (IBAction)changeContentOffset:(id)sender {
[self.collectionView setContentOffset:CGPointMake(nextCellXValue, 0) animated:YES]
}

Related

Collection View Cell Size Is Not As Expected

I'm trying to make a custom keyboard using storyboard. I need to use two collection views. I want the height and width of collection view cell as the height of collection view itself. Constraints are set properly. But cell size is not looking as expected. It is same as what height collection view has on the storyboard.
Here is the code.
#import "MainViewController.h"
#import "UpperCollectionViewCell.h"
#import "LowerCollectionViewCell.h"
#interface MainViewController () <UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
#property (weak, nonatomic) IBOutlet UICollectionView *upperCollectionView;
#property (weak, nonatomic) IBOutlet UICollectionView *lowerCollectionView;
#property (strong, nonatomic) NSArray *upperData;
#property (strong, nonatomic) NSArray *lowerData;
#end
#implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"View Presented");
self.lowerCollectionView.delegate = self;
self.lowerCollectionView.dataSource = self;
self.upperCollectionView.delegate = self;
self.upperCollectionView.dataSource = self;
self.upperData = #[[[DataModel alloc] initWithTitle:#"Bollywood" subtitle:nil color:[UIColor orangeColor]],
[[DataModel alloc] initWithTitle:#"Hollywood" subtitle:nil color:[UIColor greenColor]],
[[DataModel alloc] initWithTitle:#"Tollywood" subtitle:nil color:[UIColor magentaColor]]];
self.lowerData = #[[[DataModel alloc] initWithTitle:#"News" subtitle:#"Very first comment" color:[UIColor blueColor]],
[[DataModel alloc] initWithTitle:#"Tasks" subtitle:#"Second comment" color:[UIColor redColor]],
[[DataModel alloc] initWithTitle:#"Events" subtitle:#"Third comment" color:[UIColor greenColor]]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if(collectionView == self.lowerCollectionView) {
return self.lowerData.count;
}
else if(collectionView == self.upperCollectionView) {
return self.upperData.count;
}
else {
return 0;
}
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
if(collectionView == self.lowerCollectionView) {
LowerCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"lower_cv_cell" forIndexPath:indexPath];
[cell setDataModel:self.lowerData[indexPath.row]];
[cell layoutIfNeeded];
return cell;
}
else if(collectionView == self.upperCollectionView) {
UpperCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"upper_cv_cell" forIndexPath:indexPath];
[cell setDataModel:self.upperData[indexPath.row]];
[cell layoutIfNeeded];
return cell;
}
else {
return nil;
}
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
if(collectionView == self.lowerCollectionView) {
CGSize size = CGSizeMake(collectionView.bounds.size.height, collectionView.bounds.size.height-10);
NSLog(#"lower height : %#",NSStringFromCGSize(size));
return size;
}
else if(collectionView == self.upperCollectionView) {
CGSize size = CGSizeMake(collectionView.bounds.size.height, collectionView.bounds.size.height-10);
NSLog(#"upper height : %#",NSStringFromCGSize(size));
return size;
}
else {
return CGSizeZero;
}
}
#end
Unable to figure out why cell size is not as expected.

IOS UICollectionView Cell with different instance of cell class

I am trying to create custom cell for UiCollectionView where I need to update each cell from background.
So I have created custom class for each cell named Cell_Obj and updating the cell content from the Cell_Obj itself using a timer.
The below code add an image on cell and increment a counter in each 2 second and display it on new cell label.
On each time when I add new cell using a button on a viewcotroller the cell updating but every cell getting the same value on the label. It suppose to have different counter value as each cell is different instance of Cell_Obj but the counter value and labelTxt(the cell number) has the same value when each time the timer triggered.
ViewController.h
#import <UIKit/UIKit.h>
#import "Cell_Obj.h"
#interface ViewController : UIViewController<UICollectionViewDataSource,UICollectionViewDelegate>
#property (weak, nonatomic) IBOutlet UICollectionView *collection;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController (){
NSMutableArray *GridArray;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.collection setDelegate:self];
[self.collection setDataSource:self];
// Do any additional setup after loading the view, typically from a nib.
GridArray = [[NSMutableArray alloc] init];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return GridArray.count;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (Cell_Obj *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
Cell_Obj *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
// cell.label.text = #"123";
/*cell.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"AppIcon.png",indexPath.row]];*/
return cell;
}
- (void)addImage
{
Cell_Obj *cell = [[Cell_Obj alloc] init];
// cell.label.text = #"123";
//cell.label.text = [NSString stringWithFormat:#"%d",[dvrGridArray count]-1];
NSString * txt = [NSString stringWithFormat:#"%d",[GridArray count]];
[cell updateTextLabelName: txt];
[GridArray addObject:cell];
[_collection insertItemsAtIndexPaths:#[[NSIndexPath indexPathForItem:[GridArray count]-1 inSection:0]]];
/* NSMutableArray *arrayWithIndexPaths = [NSMutableArray array];
[arrayWithIndexPaths addObject:cell];
[self.collection insertItemsAtIndexPaths:arrayWithIndexPaths];*/
}
- (IBAction)addClicked:(id)sender {
[self addImage];
}
- (IBAction)changeImage:(id)sender {
// DVR_Obj *cell = [dvrGridArray objectAtIndex:0];
// [cell changeImage ];
// [_collection reloadData];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:0];
Cell_Obj *cell = [_collection cellForItemAtIndexPath:indexPath];
[cell changeImage ];
}
#pragma mark Collection view layout things
// Layout: Set cell size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
//NSLog(#"SETTING SIZE FOR ITEM AT INDEX %d", indexPath.row);
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
CGSize mElementSize = CGSizeMake((screenWidth/4)-2, (screenHeight/4)-2);
return mElementSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 1.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 1.0;
}
// Layout: Set Edges
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
// return UIEdgeInsetsMake(0,8,0,8); // top, left, bottom, right
return UIEdgeInsetsMake(1,1,1,1); // top, left, bottom, right
}
#end
Cell_Obj.h
#import <UIKit/UIKit.h>
#interface Cell_Obj : UICollectionViewCell
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
#property (weak, nonatomic) IBOutlet UILabel *label;
- (void)changeImage;
- (void)updateTextLabelName:(NSString*)str;
#end
Cell_Obj.m
#import "Cell_Obj.h"
static NSString *labelTxt ;// = [[NSString alloc] init];
static int counter;
#implementation Cell_Obj{
}
+ (void)initialize {
if (self == [Cell_Obj class]) {
labelTxt = [[NSString alloc] init];
counter=0;
}
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)awakeFromNib {
_imageView.image = [UIImage imageNamed:#"flower1.png"];
_label.text = labelTxt;
[NSTimer scheduledTimerWithTimeInterval:2.0f
target:self
selector:#selector(updateImage)
userInfo:nil
repeats:YES];
}
- (void)updateImage
{
_imageView.image = [UIImage imageNamed:#"AppIcon.png"];
counter++;
NSString * txt = [NSString stringWithFormat:#"%#-%d",labelTxt,counter];
_label.text = txt;
}
- (void)updateTextLabelName :(NSString*)str
{
labelTxt = str;
}
#end
Your each cell is not new cell. Cell_Obj *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath]; this statement reuses your cell with identifier "Cell". To create new cell each time , don't pass indexPath, pass nil instead.

Toggle cell size button not changing cell identifier UIViewController

i have created some code in my button to toggle between my cell identifier of which does so pretty well but obviously i needed to set and initial cell identifier of which is small icon, so how would i go about remove that cell identifier and replacing it with another once the button is clicked. My current code is as follows:
GroupsViewController.m
#import "GroupsViewController.h"
#import "CustomCell.h"
#interface GroupsViewController ()
{
NSArray *arrayOfImages;
NSArray *arrayOfDescriptions;
}
#end
#implementation GroupsViewController
{
NSString *reuseIdentifier;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[self GroupsCollectionView]setDataSource:self];
[[self GroupsCollectionView]setDelegate:self];
reuseIdentifier= #"SmallIcon";
arrayOfImages = [[NSArray alloc]initWithObjects:#"?.png", nil];
arrayOfDescriptions = [[NSArray alloc]initWithObjects:#"?", nil];
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [arrayOfDescriptions count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
[[cell IconImage]setImage:[UIImage imageNamed:[arrayOfImages objectAtIndex:indexPath.item]]];
[[cell IconLabel]setText:[arrayOfDescriptions objectAtIndex:indexPath.item]];
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
//Dispose of any resources that can be recreated.
}
- (IBAction)cellToggleAction:(id)sender {
if([reuseIdentifier isEqualToString:#"SmallIcon"])
reuseIdentifier=#"ListView";
else if
([reuseIdentifier isEqualToString:#"ListView"])
reuseIdentifier=#"LargeIcon";
else if
([reuseIdentifier isEqualToString:#"LargeIcon"])
reuseIdentifier=#"SmallIcon";
[self.GroupsCollectionView reloadData];
}
#end
CustomCell.h
#import <UIKit/UIKit.h>
#interface CustomCell : UICollectionViewCell
#property (weak, nonatomic) IBOutlet UIImageView *IconImage;
#property (weak, nonatomic) IBOutlet UILabel *IconLabel;
#end
I assume its to do with me setting the reuseIdentifier in the
- (void)viewDidLoad so that i didn't get any errors so that i hadn't set one, so really what i am asking for is a way to set the initial reuseidzntifier and replace it will the following when i toggle between the button clicks.
Also it would be helpful if someone could point me in the right direction as to adding icon images to each click of the button.
The problem happens when i am clicking the button as shown in the following images, the cells themselves change but the initial cell identifier stays put.
From what I understand your UICollectionViewCells are working fine. You just need to adjust their size when cells are toggled.
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGSize cellSize;
// Return required size based on your identifiers
if([reuseIdentifier isEqualToString:#"SmallIcon"])
cellSize = CGSizeMake(50, 50); // Sample size
else if
([reuseIdentifier isEqualToString:#"ListView"])
cellSize = CGSizeMake(80, 80); // Sample size
else if
([reuseIdentifier isEqualToString:#"LargeIcon"])
cellSize = CGSizeMake(120, 120); // Sample size
return cellSize;
}

How to save button selection on UITableViewCell?

My app has a favourite button, on clicking it is converting into red heart and if I click againg then it is back to gray heart. Its working correct. But problem is reuseIdentifier,After scrolling, button just coming to original state because its resusing cell here.
How can I save selection of button so that they remain selected(if selected)
Code of tableViewCell class(.h file):
#import <UIKit/UIKit.h>
#interface favBTNTableViewCell : UITableViewCell
#property(nonatomic)UIButton *faVbtn;
#end
Code of tableViewCell class(.m file)
#import "favBTNTableViewCell.h"
#implementation favBTNTableViewCell
#synthesize faVbtn;
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(nullable NSString *)reuseIdentifier
{
self=[super initWithStyle:style reuseIdentifier:reuseIdentifier];
if(self)
{
faVbtn=[UIButton new];
[faVbtn setFrame:CGRectMake(10, 10, 25, 25)];
[faVbtn setBackgroundImage:[UIImage imageNamed:#"unsel"] forState:UIControlStateNormal];
[faVbtn addTarget:self action:#selector(clickOnfav) forControlEvents:UIControlEventTouchUpInside];
[faVbtn setSelected:YES];
[self.contentView addSubview:faVbtn];
}
return self;
}
-(void)clickOnfav
{
if ([faVbtn isSelected]) {
[faVbtn setBackgroundImage:[UIImage imageNamed:#"sel.jpg"] forState:UIControlStateNormal];
[faVbtn setSelected:NO];
}
else
{
[faVbtn setSelected:YES];
[faVbtn setBackgroundImage:[UIImage imageNamed:#"unsel"] forState:UIControlStateNormal];
}
}
Code of ViewContrller.m
#import "ViewController.h"
#import "favBTNTableViewCell.h"
#interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
{
NSString *ci;
}
#property (strong, nonatomic) IBOutlet UITableView *tv;
#end
#implementation ViewController
-(NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 30;
}
-(UITableViewCell*)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
favBTNTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ci];
if(!cell)
{
cell=[[favBTNTableViewCell alloc]init];
cell.faVbtn.tag=indexPath.row;
}
return cell;
}
- (void)viewDidLoad {
_tv.delegate=self;
_tv.dataSource=self;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
You need corresponding data source for your cells. For this purpose you can, for example, create one more class and you will use it like an item for data source. Take a look:
#interface DataSourceItem : NSObject
#property (nonatomic, assign) BOOL isFavorite;
#end
#implementation DataSourceItem
#end
Then in view controller's code you need to populate array of data source items and manage your table view depending on this array:
#interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
{
NSString *ci;
}
#property (strong, nonatomic) IBOutlet UITableView *tv;
#property (strong, nonatomic) NSArray *dataSourceArray;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_tv.delegate=self;
_tv.dataSource=self;
NSMutableArray *temp = [NSMutableArray new];
// actually how many rows you table view need to have
for (NSUInteger i = 0; i < 30; i++)
{
[temp addObject:[DataSourceItem new]];
}
self.dataSourceArray = [temp copy];**
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// change dataSource item state
DataSourceItem *item = [self.dataSourceArray objectAtIndex:indexPath.row];
item.isFavorite = !item.isFavorite;
// change cell state
favBTNTableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
cell.faVbtn.selected = item.isFavorite;
}
-(NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.dataSource count];
}
-(UITableViewCell*)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
favBTNTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ci];
if(!cell)
{
cell=[[favBTNTableViewCell alloc]init];
cell.faVbtn.tag=indexPath.row;
}
// decision based on data source item state
cell.favBtn.selected = self.dataSource[indexPath.row];
return cell;
}
You can fix it like this:
Implement - (void)layoutSubviews method in your custom cell.
In - (void)layoutSubviews, check button state and then set the
right image on it:
->
- (void)layoutSubviews {
[super layoutSubviews];
UIImage *buttonImage = [faVbtn isSelected] ? [UIImage imageNamed:#"sel.jpg"] : [UIImage imageNamed:#"unsel"];
[faVbtn setBackgroundImage:buttonImage forState:UIControlStateNormal];
}
if you are using custom cell
register class/nib for your tableview in did load
[tblName registerNib:[UINib nibWithNibName:#"customCell" bundle:nil] forCellReuseIdentifier:#"customCell"];
henceforth in datasource method
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCell *cell =(customCell*) [tableView dequeueReusableCellWithIdentifier:#"customCell" forIndexPath:indexPath];
// your code here
return cell;
}
Do not forget to assign your cell identifier as "customCell" in cell attribute
Happy coding..
you can also check similar ans by me
Iphone: Checkmarks in UITableview get mixed up when scrolling

TableView UILabel alignment changes when scrolling

I have a TableView with 3 UILabel: title, author name and category and a UIImage. All cells should look similar to this layout:
Correct cell layout:
When the app starts for some reason some cells have the title UILabel alignment not as it should be:
After scrolling the TableView a few times, these cells end up with the proper alignment. I'm not quite sure what is causing this.
I have created a Custom TableView Cell class (followed this tutorial)
CustomTableViewCell.h
#interface CustomTableViewCell : UITableViewCell
#property (nonatomic, weak) IBOutlet UIImageView *image;
#property (nonatomic, weak) IBOutlet UILabel *titleLabel;
#property (nonatomic, weak) IBOutlet UILabel *authorLabel;
#property (nonatomic, weak) IBOutlet UILabel *categoryLabel;
#end
CustomTableViewCell.m
#implementation CustomTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)awakeFromNib
{
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self.contentView layoutIfNeeded];
self.titleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.titleLabel.frame);
[self.titleLabel sizeToFit];
[self.titleLabel setNumberOfLines:0];
}
#end
This is how this class is implemented in the ViewController:
#interface CurrentIssueViewController () {
CurrentIssueModel *_currentIssueModel;
Article *_selectedArticle;
}
#end
#implementation CurrentIssueViewController
static NSString *cellIdentifier = #"BasicCell";
UIActivityIndicatorView *activityView;
//#synthesize _feedItems;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didChangePreferredContentSize:)name:UIContentSizeCategoryDidChangeNotification object:nil];
// Create array object and assign it to _feedItems variable
self._feedItems = [[NSArray alloc] init];
// Create new HomeModel object and assign it to _homeModel variable
_currentIssueModel = [[CurrentIssueModel alloc] init];
// Set this view controller object as the delegate for the home model object
_currentIssueModel.delegate = self;
// Call the download items method of the home model object
[_currentIssueModel downloadItems];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil];
}
- (void)didChangePreferredContentSize:(NSNotification *)notification
{
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)itemsDownloaded:(NSArray *)items
{
// This delegate method will get called when the items are finished downloading
// Set the downloaded items to the array
self._feedItems = items;
[activityView stopAnimating];
// Reload the table view
[self.tableView reloadData];
}
#pragma mark Table View Delegate Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of feed items (initially 0)
return self._feedItems.count;
}
/* ================================================== */
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
[self configureCell:cell forRowAtIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell isKindOfClass:[CustomTableViewCell class]])
{
CustomTableViewCell *textCell = (CustomTableViewCell *)cell;
Article *article_item = self._feedItems[indexPath.row];
NSString *fulltitle = article_item.Title;
if (article_item.Subtitle != nil && article_item.Subtitle.length != 0) {
fulltitle = [fulltitle stringByAppendingString:#": "];
fulltitle = [fulltitle stringByAppendingString:article_item.Subtitle];
}
textCell.titleLabel.text = fulltitle;
if ([article_item.Author isEqualToString:#"accountant"]) {
textCell.authorLabel.text = #"";
}
else {
textCell.authorLabel.text = article_item.Author;
}
textCell.categoryLabel.text = article_item.Cat_Name;
textCell.titleLabel.numberOfLines = 0;
textCell.titleLabel.font = [UIFont fontWithName:#"Arial" size:12.0f];
textCell.authorLabel.font = [UIFont fontWithName:#"Arial" size:10.0f];
textCell.categoryLabel.font = [UIFont fontWithName:#"Arial" size:10.0f];
textCell.categoryLabel.textAlignment = NSTextAlignmentRight;
NSURL *url;
if ([article_item.ImageUrl length] != 0) {
url = [NSURL URLWithString:article_item.ImageUrl];
}
else {
url = [NSURL URLWithString:#"imageurl"];
}
[textCell.image sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:#"default_image.jpg"]];
}
}
- (CustomTableViewCell *)prototypeCell
{
if (!_prototypeCell)
{
_prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:cellIdentifier];
}
return _prototypeCell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
[self configureCell:self.prototypeCell forRowAtIndexPath:indexPath];
self.prototypeCell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.bounds), CGRectGetHeight(self.prototypeCell.bounds));
[self.prototypeCell layoutIfNeeded];
CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height+1;
}
/* ================================================== */
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set selected article to var
_selectedArticle = self._feedItems[indexPath.row];
[self performSegueWithIdentifier:#"detailSegue" sender:self];
}
#pragma mark Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get reference to the destination view controller
ArticleViewController *articleVC = segue.destinationViewController;
// Set the property to the selected article so when the view for
// detail view controller loads, it can access that property to get the feeditem obj
articleVC.selectedArticle = _selectedArticle;
}
#end
I guess it's something to do with forRowAtIndexPath but I can't really figure out what's the issue.
Update:
I noticed that there is another problem with the title UILabel. Whenever you select a cell, view the article in another ViewController and go back to the UITableView the title labels are positioned in the Center Left rather than Top Left. Once you scroll again the title labels adjust to the proper position.
You have auto layout selected for the NIB/Storyboard but have not added any constraints to your cells. Add layout constraints to your cells. There is a great answer here that explains it in some details:

Resources