How to animate height of UIDatePickerView? - ios

I have static UITableViewCell with a hidden datePickerView in it. When a button gets selected, the datePickerView becomes visible, and the cells height becomes bigger. Here is the code:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 1)
{
if (self.datePickerView.hidden == YES) {
return 252 - self.datePickerView.bounds.size.height;
}
else return 252;
}
tableView.estimatedRowHeight = 150;
return UITableViewAutomaticDimension;
}
- (IBAction)datePicker:(id)sender
{
if (self.datePickerView.hidden == YES)
{
[self.datePickerView setHidden:NO];
[self.datePickerView setFrame:CGRectMake(self.datePickerView.frame.origin.x, self.datePickerView.frame.origin.y, self.datePickerView.frame.size.width, 0)];
[UIDatePicker animateWithDuration:1.0 animations:^(){
[self.datePickerView setFrame:CGRectMake(self.datePickerView.frame.origin.x, self.datePickerView.frame.origin.y, self.datePickerView.frame.size.width, self.datePickerView.frame.size.height)];
}];
} else {
[self.datePickerView setHidden:YES];
}
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
When the datePickerView becomes visible, and the cells height gets bigger, the cells height animates, but the datePickerView doesn't. I tried to animate its height so it should be synced with the cell, but it's not?

When you are setting datePickerView's frame in animation, you are not changing it at all. Try this instead:
CGFloat originalHeight = self.datePickerView.frame.size.height;
[self.datePickerView setFrame:CGRectMake(self.datePickerView.frame.origin.x, self.datePickerView.frame.origin.y, self.datePickerView.frame.size.width, 0)];
[UIDatePicker animateWithDuration:1.0 animations:^(){
[self.datePickerView setFrame:CGRectMake(self.datePickerView.frame.origin.x, self.datePickerView.frame.origin.y, self.datePickerView.frame.size.width, originalHeight)];
}];

Related

Add UIView at the top of UITableView

I have a UITableView and view above it. Sometimes I have a lot of content so this header should be scrolled up and have to be immediatelly shown when I scroll down (like Facebook app). And I have a pull to refresh control so when I pulled down to pull to refresh my header UIView should be above UITableView (if I use a UITableViewHeaderit moves down with UITableView). What can you advice? I've really stucked. Thanks in advance.
#pragama mark delegate UIScrollView
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[self scrollViewAnimation:scrollView];
}
-(void)scrollViewAnimation:(UIScrollView *)scrollView{
if (scrollView==YourtableViewName) {
[YourtableViewName layoutIfNeeded];
if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].y > 0) {
NSLog(#"Scrolling Up");
[UIView animateWithDuration:0.25 animations:^{
viewTop_topConstraint.constant = 0;
[self.view updateConstraintsIfNeeded];
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
} else if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].y < 0) {
NSLog(#"Scrolling Down");
if (dataArray.count>4) {
[UIView animateWithDuration:0.25 animations:^{
viewTop_topConstraint.constant = -120;
[self.view updateConstraintsIfNeeded];
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
}
}
I tried a little to implement what you wanted. And I came up with this piece of code. But you might have to do a few tweaks yourself. I just set sectionHeight variable to 60 and used that to return that as section height. Make sure you set this variable to 60 (or the height of your view) in viewDidLoad or viewWillAppear method. And return the UIView you want to show above your UITableView in viewForHeaderInSection method. Let me know if you have any confusions regarding the code.
#pragma mark - TableView Data Source Events
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"DeliveryPackageCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = #"1";
return cell;
}
#pragma mark - TableView Delegate Events
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width,sectionHeight)];
[view setBackgroundColor:[UIColor lightGrayColor]];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return sectionHeight;
}
#pragma mark - Srcoll View Delegates
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
self.initialContentOffset = scrollView.contentOffset.y;
self.previousContentDelta = 0.f;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat prevDelta = self.previousContentDelta;
CGFloat delta = scrollView.contentOffset.y - self.initialContentOffset;
if (delta > 0.f && prevDelta <= 0.f) {
// started scrolling positively
if(sectionHeight != 0)
{
sectionHeight = 0;
[tableView reloadData];
}
} else if (delta < 0.f && prevDelta >= 0.f) {
// started scrolling negatively
if(sectionHeight == 0)
{
sectionHeight = 60;
[tableView reloadData];
}
}
self.previousContentDelta = delta;
}

UIDatePickers height is not animating?

I have a UIDatePicker in a static UITableViewCell with auto layout applied (to the datePicker). The datePicker is hidden until a button is selected. When the button is selected, the datePicker becomes visible, and the cells height gets bigger.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 1)
{
if (self.datePickerView.hidden == YES) {
return 252 - self.datePickerView.bounds.size.height;
}
else return 252;
}
tableView.estimatedRowHeight = 150;
return UITableViewAutomaticDimension;
}
- (IBAction)datePicker:(id)sender
{
if (self.datePickerView.hidden == YES)
{
[self.datePickerView setHidden:NO];
CGFloat originalHeight = 162;
[self.datePickerView setFrame:CGRectMake(self.datePickerView.frame.origin.x, self.datePickerView.frame.origin.y, self.datePickerView.frame.size.width, 0)];
[UIDatePicker animateWithDuration:1.0 animations:^(){
[self.datePickerView setFrame:CGRectMake(self.datePickerView.frame.origin.x, self.datePickerView.frame.origin.y, self.datePickerView.frame.size.width, originalHeight)];
}];
} else {
[self.datePickerView setHidden:YES];
}
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
When the button gets selected, the cells height is animated, but the datePicker isn't. It just appears, and gets in the way of everything until the cell is finished animating.
How can I get the datePicker to animate its height, so it should animate together with the cell?
Updating frames would not work with auto-layout. you'll have to update your constraint to do the animation.
In your case, you should have separate cell for your datePickerview and insert/ remove the cell from your tableview in order to hide and show the pickerview with animation.
[Edited]
Sample Code here: http://www.filedropper.com/tableviewsample

How to simultaneously animate a cell and table change in iOS?

I am trying to simultaneously animate a custom UITableViewCell and the UITableView that contains it.
When clicked, the subviews of the UITableViewCell slightly re-arrange such that the height of the cell increases. I want the re-arrangement within the cell to happen concurrently with the resizing of the UITableView's slot for that cell, so that it doesn't overlap with the cell below it.
When clicked again, the reverse is to happen.
This is what I've tried so far.
The UITableView
When the UITableView is clicked, I use didSelectRowAtIndexPath to update a selectedPath property:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.selectedPath && indexPath.row == self.selectedPath.row) {
self.selectedPath = nil;
} else {
self.selectedPath = indexPath;
}
[tableView reloadData];
}
Note, it calls reloadData, which triggers each visible cell to re-fetch the prototype and configure it based on whether it is selected or not:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
QueueItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"QueueCell" forIndexPath:indexPath];
[cell setImage:[UIImage imageNamed:[self.imageList objectAtIndex:indexPath.row]]];
if (self.selectedPath && indexPath.row == self.selectedPath.row) {
[cell makeSelected:YES];
} else {
[cell makeSelected:NO];
}
return cell;
}
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*) indexPath {
CGFloat height = 210;
if (indexPath.row == [self.imageList count] - 1) {
height += 10;
}
if (self.selectedPath && indexPath.row == self.selectedPath.row) {
height += 35;
}
return height;
}
The UITableViewCell subclass
In the custom cell class, its animation happens when it is made selected or not selected:
- (void)makeSelected:(BOOL)selected {
if (selected) {
[UIView animateWithDuration:0.5 animations:^{
self.customImage.frame = CGRectMake(5, 5, 310, 210);
}];
} else {
[UIView animateWithDuration:0.5 animations:^{
self.customImage.frame = CGRectMake(10, 10, 300, 200);
}];
}
}
What is happening
The table view immediately snaps to the new the allotted height for the cell, and then the cell's contents slowly animate to the new state. I want the two things to happen concurrently, and smoothly.
You might want to call
[UIView animateWithDuration:0.5 animations:^{
[self.tableView reloadData];
}];
and re-write the custom cell as following:
- (void)makeSelected:(BOOL)selected {
if (selected) {
self.customImage.frame = CGRectMake(5, 5, 310, 210);
} else {
self.customImage.frame = CGRectMake(10, 10, 300, 200);
}
}
I hope it helps.
try this... reload particular cell insteade
NSIndexPath* indexPath1 = [NSIndexPath indexPathForRow:selectedRowIndexPath inSection:section];
// Add them in an index path array
NSArray* indexArray = [NSArray arrayWithObjects:indexPath1, nil];
// Launch reload for the two index path
[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
You need to reload particular cell while tap use like this..
- (void)makeSelected:(BOOL)selected {
if (selected) {
self.customImage.frame = CGRectMake(5, 5, 310, 210);
} else {
self.customImage.frame = CGRectMake(10, 10, 300, 200);
}
}
Declare BOOl isSelect; as Global
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.selectedPath && indexPath.row == self.selectedPath.row) {
isSelect = NO;
} else {
self.selectedPath = indexPath;
isSelect = YES;
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
QueueItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"QueueCell" forIndexPath:indexPath];
[cell setImage:[UIImage imageNamed:[self.imageList objectAtIndex:indexPath.row]]];
if (self.selectedPath && indexPath.row == self.selectedPath.row && isSelect) {
[cell makeSelected:YES];
} else {
[cell makeSelected:NO];
}
return cell;
}
- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*) indexPath {
CGFloat height = 210;
if (indexPath.row == [self.imageList count] - 1) {
height += 10;
}
if (self.selectedPath && indexPath.row == self.selectedPath.row && isSelect) {
height += 35;
}
return height;
}
It reload the cell with animation.. I hope it will help you.. Now you check it will work as you want...

UIView not resizing within UITableViewCell on scroll

I have a UIView on every UITableViewCell.. This UIView has a event for touch to make it grow in height.
When user taps on this UIView the grow animation works fine, and then i mark a flag to indicate that this cell have a bigger UIView.
But when i need recycle that cell and make her bigger automatically the UIView won't grows when the UITableView displays the cell again. If i change the backgroundColor it displays the change, but don't work if i change their frame height.
A sample code:
Custom UIViewController - UITableViewDelegate, UITableViewDataSource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([_dataSource count] > 0)
{
Model *model = [_dataSource objectAtIndex:indexPath.row];
ModelCellView *cell = [model getViewFor: tableView];
return cell;
}
return nil;
}
My Model with data
- (ModelCellView*)getViewFor:(UITableView *)tableView
{
NSString *cellIdentifier = #"ModelCell";
ModelCellView *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[ModelCellView alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
//Lots of code
// Reset actionbar (UIView) to specific size
[cell.actionBar resetToState: _actionBarOpened];
//Lots of code
return cell;
}
My custom UIView class (ActionBar) inside custom UITableViewCell
- (void)resetToState:(BOOL)opened;
{
if(opened)
{
_closed = NO;
//[self open]; //tried to change de frame height here, but dont work too.
}
else
{
_closed = YES;
//[self close]; //tried to change de frame height here, but dont work too.
}
[self setNeedsLayout];
}
- (void)layoutSubviews
{
if(!_closed)
{
// This dont work
int sizeToGrow = 60;
[self setFrame: CGRectMake(
_defaultPosition.x,
_defaultPosition.y - sizeToGrow,
_defaultSize.width,
_defaultSize.height + sizeToGrow)];
// This work
self.backgroundColor = [UIColor redColor];
// This work
[_saveButton setFrame: CGRectMake(
_saveButton.frame.origin.x,
INSIDE_VIEW_Y_POSITION,
_saveButton.frame.size.width,
_saveButton.frame.size.height)];
// This work
[_deleteButton setFrame: CGRectMake(
_deleteButton.frame.origin.x,
INSIDE_VIEW_Y_POSITION,
_deleteButton.frame.size.width,
_deleteButton.frame.size.height)];
}
else
{
// This dont work
[self setFrame: CGRectMake(
_defaultPosition.x,
_defaultPosition.y,
_defaultSize.width,
_defaultSize.height)];
// This work
self.backgroundColor = [UIColor greenColor];
// This work
[_saveButton setFrame: CGRectMake(
_saveButton.frame.origin.x,
OUTSIDE_VIEW_Y_POSITION,
_saveButton.frame.size.width,
_saveButton.frame.size.height)];
// This work
[_deleteButton setFrame: CGRectMake(
_deleteButton.frame.origin.x,
OUTSIDE_VIEW_Y_POSITION,
_deleteButton.frame.size.width,
_deleteButton.frame.size.height)];
}
[super layoutSubviews];
}

scroll table view top when selecting an textfield

I Have a UITableView with custom cell with UITextField and buttons on that ,my issue is when ever the user selects some textfields in bottom keybord is hiding that textfield , i tried to scroll up the UITableView by seeing some answers in stackoverflow. but it is not scrolling can any one help me in finding out the mistake made by me please.i have written code for scrolling in textFieldDidBeginEditing: method .textFieldDidBeginEditing: is also firing and executing the code in that but it is not scrolling up.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
// NSLog(#"No OF rows:%d",[contents count]);
return [contents count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
static NSString *cellIdentifier = #"cell";
// Try to retrieve from the table view a now-unused cell with the given identifier.
cell = (uploadCustomCell *)[tableView dequeueReusableCellWithIdentifier:#"uploadCustomCell"];
if (cell == nil) {
cell = [[uploadCustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"uploadCustomCell"];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"uploadCustomCell"
owner:self options:nil];
cell = [nib objectAtIndex:0];
}
saveBtnCcell.hidden = YES;
cell.textNamefield.hidden = YES;
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell.defaultSwitch setEnabled:NO];
dictionaryContents = [contents objectAtIndex:indexPath.row];
cell
.nameLabelCell.text = [dictionaryContents valueForKey:#"VideoName"];
cell.userName.text = [dictionaryContents valueForKey:#"User"];
cell.thumbImg.image = [arrayimage objectAtIndex:indexPath.row];
NSString *defaultVideo = [dictionaryContents valueForKey:#"DefaultVideo"];
if ([defaultVideo isEqual: #"1"]) {
[defaultSwitche setOn:YES animated:YES];
}
else{
[defaultSwitche setOn:NO animated:YES];
}
[cell.defaultSwitch addTarget:self action:#selector(setState:)forControlEvents:UIControlEventValueChanged];
VideoNameTextField.hidden = YES;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 207;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
// selectedRow=indexPath.row;
indexpathTest = indexPath.row;
[tabelView1 reloadData];
NSMutableArray *dictionary = [contents objectAtIndex:indexPath.row];
guid = [dictionary valueForKey:#"GUID"];
detailsVehImg.image = [arrayimage objectAtIndex:indexPath.row];;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
{
return UITableViewCellEditingStyleDelete;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[self.tabelView1 scrollToRowAtIndexPath:1 atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
You should listen to the keyboard notifications and change your table view frame to show the cell you want. Scrolling isn't enough as if the cell is at the bottom it will be hidden anyway
-(void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillDisappear:)
name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillAppear:)
name:UIKeyboardWillShowNotification
object:nil];
}
-(void)viewDidUnload
{
[super viewDidUnload];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)keyboardWillAppear:(NSNotification *)note
{
CGRect tableViewFrame = self.tableView.frame;
// If your table view doesn't end at the bottom of the screen then this calculation of the height wouldn't be enough, you would need to take into consideration the distance between the screen bottom and the table view
tableViewFrame.size.height = tableViewFrame.size.height - [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
CGRect visibleFrame = CGRectZero;
visibleFrame.origin = self.tableView.contentOffset;
visibleFrame.size = tableViewFrame.size;
[UIView animateWithDuration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]
delay:0
options:UIViewAnimationOptionBeginFromCurrentState | [[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]
animations:^{
self.tableView.frame = tableViewFrame;
}
completion:^(BOOL finished){
[self.tableView scrollRectToVisible:visibleFrame
animated:YES];
}];
}
-(void)keyboardWillDisappear:(NSNotification *)note
{
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.size.height = tableViewFrame.size.height + [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
[UIView animateWithDuration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]
delay:0
options:UIViewAnimationOptionBeginFromCurrentState | [[note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]
animations:^{
self.tableView.frame = tableViewFrame;
}
completion:nil];
}
Try this
[self.myTableView setContentOffset:CGPointZero animated:YES];
OR
// Table View - Scroll to top
[self.myTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
[self.myTableView reloadData];
Parameter
animated:YES show scrolling animation.
animated:NO display table after scrolling(no animation.)
You have to reload your tableView before scrolling it. I have added one line of code in your textFieldDidBeginEditing. PLease try this.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self.tabelView1 reloadData];
NSArray *indexPathsForVisibleRows = [self.tabelView1 indexPathsForVisibleRows];
NSIndexPath *selectedIndexPath = [indexPathsForVisibleRows objectAtIndex:(indexPathsForVisibleRows.count/2)];
[self.tabelView1 scrollToRowAtIndexPath:selectedIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
}
Good Luck

Resources