UITextView auto expand in UITableView - ios

I have a UITextView at the last row of UITableView. I want to auto expand the UITextView according to the text which is working fine. But as the UITextView expands, the UITableViewCell should also expand. I tried reloadRowsAtIndexPaths in textViewDidChange but that again and again reloads the cell causing the UITextView resignFirstResponder.
This is the code :
- (void)textViewDidChange:(UITextView *)textView
{
CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;
textView.frame = frame;
[tableMessageDetail beginUpdates];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(int)txtReplyBottom.tag inSection:0];
[tableMessageDetail reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableMessageDetail endUpdates];
}

Gif
Cell-AutoLayout
I add a height constraint with >= 50
Code
#interface SelfSizingCell ()<UITextViewDelegate>
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *heightConstraint;
#property (weak, nonatomic) IBOutlet UITextView *textview;
#end
#implementation SelfSizingCell
- (void)awakeFromNib {
// Initialization code
self.textview.delegate = self;
self.textview.scrollEnabled = false;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
-(void)textViewDidChange:(UITextView *)textView{
CGSize size = [textView sizeThatFits:CGSizeMake(CGRectGetWidth(self.frame), CGFLOAT_MAX)];
CGFloat height = size.height;
if (height < 50) {
self.heightConstraint.constant = 50;
}else{
self.heightConstraint.constant = height;
}
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
#end
.h
#interface SelfSizingCell : UITableViewCell
#property (weak,nonatomic)UITableView * tableView;
#end
And tableviewController
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"SelfSizingCell" bundle:nil] forCellReuseIdentifier:#"cell"];
self.tableView.estimatedRowHeight = 50;
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
}
#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 {
SelfSizingCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
cell.tableView = self.tableView;
return cell;
}

Related

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;
}

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:

Perform animations on custom UITableViewCell

I'm trying to animate a few items in a custom UITableViewCell when a user presses a button in the cell. I have set addTarget: and added a method to animate the items in the cell. I've set a tag for the button so I can get the index. In the method, I call cellForRowAtIndexPath: to get the cell the button was called on. I'm casting the object returned by cellForRowAtIndexPath: to my custom cell. After I have the custom cell, I perform the animations on the objects. The problem is the animations aren't happening. When I try setting a property on one of the items in the cell, it doesn't work either. The custom cell is not returning nil so I'm not sure of the issue. What am I doing wrong?
Here is the code I'm using to call the animations
-(void)favButtonPressed:(id)sender{
FavoritesCell *favCell = (FavoritesCell *)[self tableView:self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:[sender tag] inSection:0]];
[UIView animateWithDuration:0.2 animations:^{
favCell.picButton.alpha = 0.5;
} completion:nil];
}
One way u can do it by using custom delegate like below, hope this helps u .
i took an example of your case go through this hope this helps u
in custom cell calss define delegate protocol like below
in FavoritesCell.h
#import <UIKit/UIKit.h>
#class FavoritesCell;
#protocol CellActionDelegate <NSObject>
- (void)doAnimationForCell:(FavoritesCell *)cell forButton:(UIButton *)picButton; //in this u can pass the cell itself
#end
#interface FavoritesCell : UITableViewCell
#property (nonatomic,retain)UIButton *picButton; //i am doing a simple test, say this is your pic button
#property (nonatomic,assign) id<CellActionDelegate>cellDelegate;
#end
and in FavoritesCell.m file
#import "FavoritesCell.h"
#implementation FavoritesCell
#synthesize cellDelegate;
#synthesize picButton = _picButton;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
_picButton = [[UIButton alloc]initWithFrame:CGRectMake(20, 3, 100, 100)];
//set the property // for test
[_picButton addTarget:self action:#selector(favButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[_picButton.layer setCornerRadius:50];
[_picButton.layer setMasksToBounds:YES];
[_picButton.layer setBorderColor:[[UIColor blackColor]CGColor]];
[_picButton.layer setBorderWidth:5];
_picButton.backgroundColor = [UIColor greenColor];
[self.contentView addSubview:_picButton];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)favButtonPressed:(UIButton *)sender
{
//or you can do the animation hear only no need to delegate to controller form cell
if([self.cellDelegate respondsToSelector:#selector(doAnimationForCell:forButton:)])
{
[self.cellDelegate doAnimationForCell:self forButton:sender]; //call this method
}
}
#end
in ViewController.h file
#import <UIKit/UIKit.h>
#import "FavoritesCell.h" //import it
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,CellActionDelegate> //confirms to delegate
//.... other stuffs
in ViewController.m file
//...other stuffs
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FavoritesCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CELL"];
if(cell == nil)
{
cell = [[FavoritesCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CELL"];
}
cell.cellDelegate = self; //set the deleagte to this class
[cell.picButton setImage:[UIImage imageNamed:#"Two-Red-Flower-.jpg"] forState:UIControlStateNormal]; //set it hear or in custom cell itself
//...other logics
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 130.0f;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
//define the delegate method
- (void)doAnimationForCell:(FavoritesCell *)cell forButton:(UIButton *)picButton //this the picButton
{
//you can get index path of cell
//you can get the tapped button of the cell
//then do your animation
[UIView animateWithDuration:0.2 animations:^{
picButton.alpha = 0.5;
} completion:nil];
}
I think you want something like this:
-(void)favButtonPressed:(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.myTableView];
// or try this one alternatively if the above line give wrong indexPath
//CGPoint buttonPosition = [sender convertPoint:((UIButton *)sender).center toView:self.myTableView];
NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:buttonPosition];
// I assume "self" here is your view controller
FavoritesCell *favCell = (FavoritesCell *)[self.myTableView cellForRowAtIndexPath:indexPath];
[UIView animateWithDuration:0.2 animations:^{
favCell.picButton.alpha = 0.5;
} completion:nil];
}

Resize of section header in UITableViewController not working properly

I am trying to resize a section header, according to a selection in the headers UISegmentedControl.
For some reason, it just doesn't want to work. I have tried with [self.tableView beginUpdates]; and [self.tableView endUpdates]; before, around and after the change-height code.. but it just act weird.
I get it to hide and show content, but it seems to allocate a different height for the view even thought the size of the header should be less.
This is what happens:
https://dl.dropboxusercontent.com/u/3077127/Problem3.mov
This is my code:
typedef enum {
kSearchTypeFrom = 0,
kSearchTypeTo
} kSearchType;
#interface MainVC ()
#property (nonatomic, strong) FilterVC *filterView;
#property (nonatomic, assign) kSearchType searchType;
#end
#implementation MainVC
#synthesize filterView = _filterView;
#synthesize searchType = _searchType;
[...]
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.searchType = kSearchTypeFrom;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
- (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 = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
// Configure the cell...
[cell.detailTextLabel setText:#"Test"];
return cell;
}
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (!self.filterView) {
self.filterView = [[FilterVC alloc] init];
[self.filterView.view setBackgroundColor:self.navigationController.navigationBar.barTintColor];
}
[self.filterView.segment setSelectedSegmentIndex:self.searchType];
[self.filterView.segment addTarget:self action:#selector(didChangeSegmentSelection:) forControlEvents:UIControlEventValueChanged];
return self.filterView.view;
}
- (float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (self.searchType == kSearchTypeFrom)
{
return 130;
}
else {
return 100;
}
}
#pragma mark - Height change table section
- (void)didChangeSegmentSelection:(UISegmentedControl*)segment
{
[self.tableView beginUpdates];
self.searchType = segment.selectedSegmentIndex;
NSLog(#"Selected: %d", segment.selectedSegmentIndex);
if (segment.selectedSegmentIndex == 0)
{
[self.filterView.changeToText setHidden:NO];
[self.filterView.changeToButton setHidden:NO];
[self.filterView.fromButton setUserInteractionEnabled:NO];
}
else {
[self.filterView.changeToText setHidden:YES];
[self.filterView.changeToButton setHidden:YES];
[self.filterView.fromButton setUserInteractionEnabled:YES];
}
[self.tableView endUpdates];
[self.filterView.view needsUpdateConstraints];
}
[...]
The FilterVC class is nothing more than an UIViewController containing the following:
#import "InsetTextField.h"
#interface FilterVC : UIViewController
#property (nonatomic, strong) IBOutlet InsetTextField *amountField;
#property (nonatomic, strong) IBOutlet UISegmentedControl *segment;
#property (nonatomic, strong) IBOutlet UIButton *fromButton;
#property (nonatomic, strong) IBOutlet UILabel *changeToText;
#property (nonatomic, strong) IBOutlet UIButton *changeToButton;
#end
What is it that I am doing wrong?
As an alternate to trying to animate, you could try reloading the table using the following:
- (void)didChangeSegmentSelection:(UISegmentedControl*)segment
{
//[self.tableView beginUpdates];
self.searchType = segment.selectedSegmentIndex;
NSLog(#"Selected: %d", segment.selectedSegmentIndex);
if (segment.selectedSegmentIndex == 0)
{
[self.filterView.changeToText setHidden:NO];
[self.filterView.changeToButton setHidden:NO];
[self.filterView.fromButton setUserInteractionEnabled:NO];
}
else {
[self.filterView.changeToText setHidden:YES];
[self.filterView.changeToButton setHidden:YES];
[self.filterView.fromButton setUserInteractionEnabled:YES];
}
//[self.tableView endUpdates];
[self.tableView reloadData];
[self.filterView.view needsUpdateConstraints];
}
EDIT:
How about a variable to track height? This is sloppy code, but if the concept works, you can refactor it:
// Declare a variable
#proprty (strong, nonatomic) float headerHeight;
// Use that variable for defining the height
- (float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (self.searchType == kSearchTypeFrom)
{
headerHeight = 130;
}
else {
headerHeight = 100;
}
return headerHeight
}
Then change that variable:
- (void)didChangeSegmentSelection:(UISegmentedControl*)segment
{
[self.tableView beginUpdates];
self.searchType = segment.selectedSegmentIndex;
// Change the variable used for the header height
if (self.searchType == kSearchTypeFrom)
{
headerHeight = 130;
}
else {
headerHeight = 100;
}
NSLog(#"Selected: %d", segment.selectedSegmentIndex);
if (segment.selectedSegmentIndex == 0)
{
[self.filterView.changeToText setHidden:NO];
[self.filterView.changeToButton setHidden:NO];
[self.filterView.fromButton setUserInteractionEnabled:NO];
}
else {
[self.filterView.changeToText setHidden:YES];
[self.filterView.changeToButton setHidden:YES];
[self.filterView.fromButton setUserInteractionEnabled:YES];
}
[self.tableView endUpdates];
[self.filterView.view needsUpdateConstraints];
}

Resources