I have a tableview controller and one of the cell is "date" and when i click i wanna show a datepicker and update the values.
When i click on limit date i get
Now here is the code:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( indexPath.section == 0 )
{
if ( indexPath.row == 3 )
{
UITableViewCell *targetCell = [tableView cellForRowAtIndexPath:indexPath];
self.pickerView.date = [self.dateFormatter dateFromString:targetCell.detailTextLabel.text];
// check if our date picker is already on screen
if (self.pickerView.superview == nil)
{
[self.view.window addSubview: self.pickerView];
// size up the picker view to our screen and compute the start/end frame origin for our slide up animation
//
// compute the start frame
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGSize pickerSize = [self.pickerView sizeThatFits:CGSizeZero];
CGRect startRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height,
pickerSize.width, pickerSize.height);
self.pickerView.frame = startRect;
// compute the end frame
CGRect pickerRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height - pickerSize.height,
pickerSize.width,
pickerSize.height);
// start the slide up animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
// we need to perform some post operations after the animation is complete
[UIView setAnimationDelegate:self];
self.pickerView.frame = pickerRect;
// shrink the table vertical size to make room for the date picker
CGRect newFrame = self.tableView.frame;
newFrame.size.height -= self.pickerView.frame.size.height;
self.tableView.frame = newFrame;
[UIView commitAnimations];
// add the "Done" button to the nav bar
self.navigationItem.rightBarButtonItem = self.doneButton;
}
}
}
}
- (IBAction)dateChanged:(id)sender
{
[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:3 inSection:0]].detailTextLabel.text = [self.dateFormatter stringFromDate:[sender date]];
}
- (void)slideDownDidStop
{
[self.pickerView removeFromSuperview];
}
- (IBAction)doneAction:(id)sender
{
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGRect endFrame = self.pickerView.frame;
endFrame.origin.y = screenRect.origin.y + screenRect.size.height;
// start the slide down animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
// we need to perform some post operations after the animation is complete
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(slideDownDidStop)];
self.pickerView.frame = endFrame;
[UIView commitAnimations];
// grow the table back again in vertical size to make room for the date picker
CGRect newFrame = self.tableView.frame;
newFrame.size.height += self.pickerView.frame.size.height;
self.tableView.frame = newFrame;
// remove the "Done" button in the nav bar
self.navigationItem.rightBarButtonItem = nil;
// deselect the current table row
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
self.navigationItem.rightBarButtonItem = self.nextButton;
}
I have three questions:
First: what is that black bar on top of datepicker and how do i remove it?
Second: what can i do for closing the datepicker when the user clicks outside the datepicker?
Third: How can i move the tableview scroll so that the field "limit date" can be visible when datepicker opens?
Sorry for the big screenshots.
What about presenting your date picker modally in UIActionSheet?
In the example above that black bar (which is probably a sizing issue) is replaced with a convenient toolbar in which you can place buttons like "save" and "cancel", and I believe that if you use a UIActionSheet and click outside of it it's automatically dismissed (I'm not sure about this), but if' it's not you can use it's dismiss method to hide it.
About the table view, you can use [myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:someRow inSection:someSection] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; to set the offset of the table scroll at a particular cell you want.
Related
Every time I click on my UISegementedControl it snaps back to its original frame. I can see it barely through my translucent toolbar.
I have a UIViewController with a UITableView, and UIToolBar like this:
There is a UISegmentedControl hidden just below the table view, behind the toolbar:
The Filter button calls the 'onFilterButtonPressed' method
- (IBAction)onFilterButtonPressed:(id)sender
{
if(self.filterBar.hidden){
[self showFilterBar];
} else {
[self hideFilterBar];
}
}
- (void)hideFilterBar
{
CGRect filterBarFrame = CGRectMake(0, self.view.frame.size.height+(self.filterBar.frame.size.height+1), self.filterBar.frame.size.width, self.filterBar.frame.size.height);
CGRect tableViewFrame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y,self.tableView.frame.size.width, self.tableView.frame.size.height+(self.filterBar.frame.size.height+1));
[UIView animateWithDuration:0.3 animations:^{
[self.filterBar setFrame:filterBarFrame];
[self.tableView setFrame:tableViewFrame];
} completion:^(BOOL finished) {
self.filterBar.hidden = YES;
}];
}
- (void)showFilterBar
{
CGRect filterBarFrame = CGRectMake(0, self.view.frame.size.height-(self.filterBar.frame.size.height+1), self.filterBar.frame.size.width, self.filterBar.frame.size.height);
CGRect tableViewFrame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y,self.tableView.frame.size.width, self.tableView.frame.size.height-(self.filterBar.frame.size.height+1));
self.filterBar.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
[self.tableView setFrame:tableViewFrame];
[self.filterBar setFrame:filterBarFrame];
}];
}
This is because of auto layout. With that turned on (which it is by default), you should do any positioning or resizing of views by modifying constraints, not setting frames.
Im very new to iOS and am trying to figure out how I can animate the tableView header to appear like its sliding down from the top of the view, stay there for 3 seconds, then slide back up and disappear.
I havent done any animation of any kind before so I could really use some help. I dont know where to start. Ive looked at other answers on here but cant seem to figure out how to do it.
ive got my table view appearing just fine with this code in my viewDidLoad of my UITableViewController class
self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320,15)];
self.headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 15)];
self.headerLabel.textAlignment = NSTextAlignmentCenter;
self.headerLabel.text = #"some text";
[self.headerView addSubview:self.headerLabel];
self.tableView.tableHeaderView = self.headerView;
self.tableView.tableHeaderView.frame = CGRectMake(0, 0, 320, 15);
I assume I need to animate the height of my frame.
edit: I found this code which seems like it should work, however it crashes my app when the animation runs
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[UIView animateWithDuration:3.0f
delay:0.0f
options: UIViewAnimationOptionBeginFromCurrentState
animations:^{
self.headerView.frame = CGRectMake(0.0f, 0.0f, 320.f, 0.0f);
}
completion:^(BOOL finished) {
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}];
}
I don't know if you can animate a table view's header view like you want to. With a complex UI object like a Table view Apple tends to treat the views that make up the object as private, and bad things tend to happen when you try to manipulate the view hierarch.
If you're not using auto-layout and you want to animate another view that is part of YOUR view hierarchy then your code might be as simple as something like this:
CGPoint center = myView.center;
CGFloat myViewBottom = myView.frame.origin.y + myView.frame.origin.size.height;
//Move the view above the top of it's superview before starting the animation.
center.y -= myViewBottom;
//Animate the view down into position
[UIView animateWithDuration: .2
animations:
^{
myView.center += myViewBottom;
};
completion:
^{
//As the completion block for the first animation, trigger another
//animation to animate the view away again. This time delay
//for 3 second before the 2nd animation.
[UIView animateWithDuration: .2
delay: 3.0
options: 0
animations:
^{
myView.center -= myViewBottom;
};
completion: nil
}
];
Try to use beginUpdates and endUpdates, here is an example:
in your header
#property NSInteger newOffset;
implementation:
- (void) colapseHeader
{
_newOffset = 50;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50 + _newOffset;
}
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
_newOffset = 100;
[self.tableView beginUpdates];
[self.tableView endUpdates];
[self performSelector:#selector(colapseHeader) withObject:nil afterDelay:3];
}
In my app I have a partially hidden toolbar whose frame is translated into view when the exposed part of the view is tapped. The translation works and the buttons on the toolbar are functional. However, the areas covered by the exposed toolbar are not tappable after the toolbar is translated to its hidden position.
Here are the relevant parts of code:
In viewDidLoad of the view controller that is displaying the toolbar:
self.filterViewController = [[LKCEventListFilterViewController alloc] initWithNibName:[LKCEventListFilterViewController nibName] bundle:nil];
self.filterViewController.delegate = self;
self.filterViewController.view.frame = CGRectMake(self.filterViewController.view.frame.origin.x, self.filterViewController.view.frame.origin.y - 60, self.filterViewController.view.frame.size.width, self.filterViewController.view.frame.size.height);
[self.view addSubview:self.filterViewController.view];
The code to display the toolbar, part of the LKCEventListFilterViewController class
- (IBAction)openTabButtonPressed:(id)sender
{
NSInteger translation = 60;
if(!self.isFilterViewOpen)
{
self.isFilterViewOpen = YES;
}
else
{
self.isFilterViewOpen = NO;
translation = -translation;
}
[UIView animateWithDuration:0.2 delay:0 options: UIViewAnimationCurveEaseOut animations:^{
CGRect frame = self.view.frame;
frame.origin.y += translation;
self.view.frame = frame;
}
completion:^(BOOL finished){ }];
}
I have a UIScrollView at the very top (just below the navigation bar) of a UITableViewController using Storyboards. The UIScrollView's default size is 320x50. When the user holds the scrollView for at least 1 second, I want the UIScrollView to get twice as big (320x100) in order to show additional details with an animation. The UITableView right below it should animate with it if possible and move down 50.
Holding the UIScrollView for at least 1 second when it's in the bigger setting will result in the opposite animation, and the UIScrollView will animate back to its original size.
How would I do this? Thank you ahead of time! Here's what I have so far:
- (void)viewDidLoad {
[super viewDidLoad];
self.featureScrollExpanded = NO;
UILongPressGestureRecognizer* featureHold = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector (longHold:)];
[featureHold setDelaysTouchesBegan : YES];
featureHold.minimumPressDuration = 0.6;
featureHold.numberOfTouchesRequired = 1;
[self.featureScrollView addGestureRecognizer:featureHold];
[featureHold release];
}
- (void)longHold:(UIGestureRecognizer*)sender {
if (self.featureScrollExpanded==NO) {
self.featureScrollExpanded=YES;
//make it bigger
}
else {
self.featureScrollExpanded=NO;
//make it smaller
}
}
Do an animation:
CGRect frame = yourScrollView.frame;
frame.size.height += 50;
[UIView animateWithDuration:0.6
animations:^{
yourScrollView.frame = frame;
} completion:^(BOOL finished) {
//do your other animation here if you want to
//or do them both together and lose this block
}
];
Or if you want it a bit more with an overview:
CGRect frame = yourScrollView.frame;
frame.size.height += 50;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:0.6];
[self.yourScrollView setFrame:frame];
[UIView commitAnimations];
I can change the position of delete button when tableviewcell in the edit style, use following code
- (void)didTransitionToState:(UITableViewCellStateMask)state
{
[super didTransitionToState:state];
if(state == UITableViewCellStateShowingDeleteConfirmationMask)
{
for (UIView *v in [self subviews])
{
if([NSStringFromClass([v class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"])
{
NSLog(#"find");
CGRect f = v.frame;
deleteView = v;
NSLog(#"delete view %#",[deleteView description]);
v.backgroundColor = [UIColor grayColor];
v.frame = CGRectMake(200, 10, f.size.width, f.size.height);
UIControl *vs = [[v subviews]objectAtIndex:0];
CGRect fs = vs.frame;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1];
fs.origin.x -=20;
vs.frame = fs;
[UIView commitAnimations];
}
}
}
}
use this way I can change the position of delete button. But each time the delete button appears, it moves in from the right side of my tableviewcell with animation, and finally it located at the position I specified..... I just want to set the button frame before it appears, but now i have no idea. my english is poor ...thanks everybody ..thanks in advance
There are two messages: tableView:willBeginEditingRowAtIndexPath: and tableView:didEndEditingRowAtIndexPath:.
I think you can use the delegate to update the appearance of the table view appropriately.