i want to hide navigationbar and tabbar on touch and move on uitableview, blow code:
_headView from viewForHeaderInSection it's no problem.
but sometimes after block Executed, _headView is visible
if(_headView)
_headView.hidden = YES; //
[UIView animateWithDuration:0.5 animations:^{
scrollView.frame = rect;
_vc.navigationController.navigationBar.top -= navigationBarHeight;
tabView.top = SCREEN_HEIGHT;
} completion:^(BOOL finished) {
}];
if i move hide code to completion block , it's run OK, but hide after 0.5 sec, it's slowly .
[UIView animateWithDuration:0.5 animations:^{
scrollView.frame = rect;
_vc.navigationController.navigationBar.top -= navigationBarHeight;
tabView.top = SCREEN_HEIGHT;
} completion:^(BOOL finished) {
if(_headView)
_headView.hidden = YES; //Delay after 0.5s.
}];
please help me , thanks.
We have a delegate method for the setting height of section for UITableView
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
just return 0 for this, for hiding header.
Related
I've scrollview with page control and I want to make the subview of my scrollview fadeIn/fadeOut when I scroll to or from the next page. I found that I can use contentOffset to make this effect but I couldn't make it.
In fact, I'm newbie and I wish If there is any tutorial that can help. thank you.
Assuming you hold an array of your view controllers in self.viewControllers indexed according to the UIPageControl:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat diffFromCenter = ABS(scrollView.contentOffset.x - (self.pageControl.currentPage)*self.view.frame.size.width);
CGFloat currentPageAlpha = 1.0 - diffFromCenter/self.view.frame.size.width;
CGFloat sidePagesAlpha = diffFromCenter/self.view.frame.size.width;
//NSLog(#"%f",currentPageAlpha);
[[[self.viewControllers objectAtIndex:self.pageControl.currentPage] view] setAlpha:currentPageAlpha];
if (self.pageControl.currentPage > 0)
[[[self.viewControllers objectAtIndex:self.pageControl.currentPage-1] view] setAlpha:sidePagesAlpha];
if (self.pageControl.currentPage < [self.viewControllers count]-1)
[[[self.viewControllers objectAtIndex:self.pageControl.currentPage+1] view] setAlpha:sidePagesAlpha];
}
You might check out this tutorial on view animation:
Uiview-tutorial-for-ios-how-to-use-uiview-animation
To achieve the effect you are looking for you can use something like this:
ScrollView delegate method to detect scrolling (if your only paging)
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
UIView* subView = [scrollView.subviews lastObject]; //Or however you access your subview
[UIView animateWithDuration:1.0f animations:^{
subView.alpha = 0.0f;
} completion:^(BOOL finished){
[UIView animateWithDuration:1.0f animations:^{
subView.alpha = 1.0f;
}];
}];
}
This will cause your subview to smoothly fade out and in within the span of 2.0 seconds. You should a bit of reading about this animation blocks though as they can be a little tricky. For instance I had nest the second animation block after the first had complete because the actual code within them is handled immediately and the animation simply takes place on the View side of things.
Hope this helps!
You can fade it to zero, change the contentOffset without animation, and fade it back to alpha with 1.0:
- (IBAction)didChangePageView:(id)sender
{
[UIView animateWithDuration:0.25
animations:^{
self.scrollView.alpha = 0.0;
}
completion:^(BOOL finished) {
[self.scrollView setContentOffset:CGPointMake(0, self.scrollView.frame.size.height * self.pageViewControl.currentPage) animated:NO];
[UIView animateWithDuration:0.25 animations:^{
self.scrollView.alpha = 1.0;
}];
}];
}
With Swift 2.0, assuming you hold an array of your subViews in myViewsArray:
func scrollViewDidScroll(scrollView: UIScrollView) {
//Fade in/out effect while scrolling
for (index,subView) in myViewsArray.enumerate() {
label.alpha = 1 - abs(abs(scrollView.contentOffset.x) - subView.frame.width * CGFloat(index)) / subView.frame.width
}
}
In my didSelectRowAtIndexPath method I call [self dismissView]; when the user selects a cell in order to dismiss the view if its already been presented. This clearly isn't very optimal and its overriding the presentView method without it animating the dismissView. Is there a better way to do this? Or at the very least let it wait for the view to finish animating without using NSTimer.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
[self dismissView];
// Do xyz...
[self presentView:twitterLinksView];
Then..
- (void)presentView:(id)sender
{
twitterLinksView.frame = CGRectMake(0, (self.view.frame.size.height + viewHeight), 320, 300);
[UIView animateWithDuration:0.60f animations:^{
CGRect twitterLinkFrame = self.twitterLinksView.frame;
twitterLinkFrame.origin.y = (self.view.frame.size.height - viewHeight);
twitterLinksView.frame = twitterLinkFrame;
}];
}
- (void)dismissView
{
[UIView animateWithDuration:0.75f animations:^{
CGRect twitterLinkFrame = self.twitterLinksView.frame;
twitterLinkFrame.origin.y = (self.view.frame.size.height + viewHeight);
self.twitterLinksView.frame = twitterLinkFrame;
}];
}
[UIView animateWithDuration:1. animations:^{
//firstAnimationBlock
} completion:^(BOOL finished){
[UIView animateWithDuration:1. animations:^{
//animations in this block will be called after firstAnimationBlock has expired
}];
}];
as i understand you wanna fire 2 animation one after the other. this code (block inside block) makes this
this part is after edit:
ok now you can try writing like that
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
[self dismissView];
// Do xyz...
[self performSelector:#selector(presentView:) withObject:twitterLinksView afterDelay:0.75];
//[self presentView:twitterLinksView];
}
I ended up splitting out my creation method and using [[self.view subviews] containsObject:twitterLinksView] to check for the view. Also to be noted is [self performSelector:#selector(createView) withObject:twitterLinksView afterDelay:0.76f] had to be very slightly ahead of the dismissing animation for it to work at all... yeah wtf.
In the didSelectRowAtIndexPath method i used [self performSelector:#selector(presentView:)];
Thanks to meth for solving part of the puzzle.
- (void)presentView:(id)sender
{
if ([[self.view subviews] containsObject:twitterLinksView])
{
[self dismissView];
[self performSelector:#selector(createView) withObject:twitterLinksView afterDelay:0.76f];
NSLog(#"Animating ut old");
}
else
{
NSLog(#"Creating new view");
[self createView];
}
}
-(void)createView
{
twitterLinksView.frame = CGRectMake(0, (self.view.frame.size.height + viewHeight), 320, 300);
[UIView animateWithDuration:0.60f animations:^{
CGRect twitterLinkFrame = self.twitterLinksView.frame;
twitterLinkFrame.origin.y = (self.view.frame.size.height - viewHeight);
twitterLinksView.frame = twitterLinkFrame;
[self.view addSubview:twitterLinksView];
}];
}
- (void)dismissView
{
[UIView animateWithDuration:0.75f animations:^{
CGRect twitterLinkFrame = self.twitterLinksView.frame;
twitterLinkFrame.origin.y = (self.view.frame.size.height + viewHeight);
self.twitterLinksView.frame = twitterLinkFrame;
}completion:^(BOOL finished){
[twitterLinksView removeFromSuperview];
}];
}
I have a method that gets called if a video upload to Facebook has failed. If that method is called then I would like for a UILabel to briefly appear in any view controller that a user happens to be on at the time the upload fails.
Is this possible?
I asked a similar question earlier about a UIAlertView, but I realized that there are certain circumstances under which an alert could negatively impact user experience.
You can do this is many ways -
1) you can add UILabel to your applications main Window.
2) if you are using a UINavigationController then you get the instance of current viewcontroller and then can add UILabel to its view.
3) if you are using a UITabBarController in this case you can also get the instance of current viewcontroller by accessing tabBarController's selected viewcontroller.
this code Im posting below is from HackBook sample app from facebook. they done similar to what you want.
- (void)showMessage:(NSString *)message {
CGRect labelFrame = messageView.frame;
labelFrame.origin.y = [UIScreen mainScreen].bounds.size.height - self.navigationController.navigationBar.frame.size.height - 20;
messageView.frame = labelFrame;
messageLabel.text = message;
messageView.hidden = NO;
// Use animation to show the message from the bottom then
// hide it.
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationCurveEaseOut
animations:^{
CGRect labelFrame = messageView.frame;
labelFrame.origin.y -= labelFrame.size.height;
messageView.frame = labelFrame;
}
completion:^(BOOL finished){
if (finished) {
[UIView animateWithDuration:0.5
delay:3.0
options: UIViewAnimationCurveEaseOut
animations:^{
CGRect labelFrame = messageView.frame;
labelFrame.origin.y += messageView.frame.size.height;
// UIView *messageView; declared in header
messageView.frame = labelFrame;
}
completion:^(BOOL finished){
if (finished) {
messageView.hidden = YES;
messageLabel.text = #"";
}
}];
}
}];
}
The main UIView contains two subviews - UIView_1 and UIView_2.
In the UIView_2, there is a button to show or hide the UIView_1.
For example, when a user touches the button to show the UIView_1, then UIView_1 will slide down and UIView_2 will push downwards with transition.
I have very little knowledge in animation. Can someone show me some sample code for reference?
Should I use CGAffineTransformMakeTranslation?
Thanks.
You don't need anything so complex. Just change the view's frame size.
NSTimeInterval animationDuration = /* determine length of animation */;
CGRect newFrameSize = /* determine what the frame size should be */;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:animationDuration];
theViewToChange.frame = newFrameSize;
[UIView commitAnimations];
Simply Hide/show with fadein/out effect
`
/To Show/
sliderView.hidden = NO;
sliderView.alpha = 0.1;
[UIView animateWithDuration:0.25 animations:^{
sliderView.alpha = 1.0f;
} completion:^(BOOL finished) {
// do some
}];
/To hide/
[UIView animateWithDuration:0.25 animations:^{
sliderView.frame = CGRectMake(130, 30, 0, 0);
[sliderView setAlpha:0.1f];
} completion:^(BOOL finished) {
sliderView.hidden = YES;
}];
`
It depends on what you want to do with UIView_2.
Place UIView_1 below UIView_2 in Interface Builder.
Size UIView_2 to take up all the space below the UINavigationBar.
Use the following code to either resize (using uiview2_resized_rect) the frame for UIView_2, or translate/move the frame for UIView_2 (using uiview2_translated_rect ):
CGRect uiview1_original_rect = UIView_1.frame;
CGRect uiview2_original_rect = UIView_2.frame;
CGRect uiview2_translated_rect = CGRectMake(uiview2_original_rect.origin.x,
uiview2_original_rect.origin.y+uiview1_original_rect.size.height,
uiview2_original_rect.size.width,
uiview2_original_rect.size.height);
CGRect uiview2_resized_rect = CGRectMake(uiview2_original_rect.origin.x,
uiview2_original_rect.origin.y+uiview1_original_rect.size.height,
uiview2_original_rect.size.width,
uiview2_original_rect.size.height-uiview1_original_rect.size.height);
[UIView animateWithDuration:0.300 delay:0.0
options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionBeginFromCurrentState
animations:^{
//uncomment this and comment out the other if you want to move UIView_2 down to show UIView_1
//UIView_2.frame = uiview2_translated_rect;
UIView_2.frame = uiview2_resized_rect;
} completion:^(BOOL finished) {
}];
I've found example of animated search-bar with scope bar under "UISearchDisplayDelegate Protocol Reference"(SearchBar-animated-sample
), here is a video preview:
SearchBarAnimated-video
I've checked sample code, but I can't find the code that triggers animation.
Does anyone knows how to create that animation ? Do you have to use UISearchBarDelegate to get that animation ?
Inorder to control the animations of UISearchBar you have implement the delegates of UISearchDisplayController by extending in your header file. The delegates are as follows;
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
[UIView beginAnimations:nil context:NULL];
self.searchDisplayController.searchBar.showsScopeBar = NO;
CGRect headerViewFrame = self.searchDisplayController.searchBar.frame;
headerViewFrame.origin.y -= 54.0f;
self.searchDisplayController.searchBar.frame = headerViewFrame;
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.origin.y -= 54.0f;
self.tableView.frame = tableViewFrame;
[UIView commitAnimations];
}
-(void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
[UIView beginAnimations:nil context:NULL];
CGRect headerViewFrame = self.searchDisplayController.searchBar.frame;
headerViewFrame.origin.y += 54.0f;
self.searchDisplayController.searchBar.frame = headerViewFrame;
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.origin.y += 54.0f;
self.tableView.frame = tableViewFrame;
[UIView commitAnimations];
}
It's built right in to UISearchBar. Apple does this for you, you don't have to call any method by yourself.
Basically, from the moment you set your search bar's scopeButtonTitles property, Apple will animate the scope bar.
I found the answer to this question more useful though it doesn't automatically transition the search bar to the top of your view.
How do you hide/show UISearchBar's scope bar with animation?
This works well for me in Xcode 6. If you have auto layout constraints in place then you may need to add in adjustments for them as I've done (didn't work without them).
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsScopeBar = YES;
searchBarHeightConstraint.constant = 88; // Changes from 44 to 88 with scope bar
tableViewHeightConstraint.constant = 480; // Changes from 524 to 480 with scope bar
[UIView animateWithDuration:0.3
animations:^{
CGRect newFrame = tableView.frame;
newFrame.origin.y = 88;
tableView.frame = newFrame;
}];
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
searchBar.showsScopeBar = NO;
searchBarHeightConstraint.constant = 44;
tableViewHeightConstraint.constant = 524;
[UIView animateWithDuration:0.3
animations:^{
CGRect newFrame = tableView.frame;
newFrame.origin.y = 44;
tableView.frame = newFrame;
}];
return YES;
}
sizeToFit in an Animation block
The UISearchBar w/ scope bar is easily animated. UISearchBar has a height of 44.f before calling sizeToFit with the scope bar and then becomes 88.f. In my case, the UISearchBar was embedded in a UITableView within Interface Builder so it was not possible to add auto layout constraints.
#pragma mark - UISearchBarDelegate methods
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
searchBar.showsScopeBar = YES;
[UIView animateWithDuration:0.2f animations:^{
[searchBar sizeToFit];
}];
[searchBar setShowsCancelButton:YES animated:YES];
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
searchBar.showsScopeBar = NO;
[searchBar sizeToFit];
[searchBar setShowsCancelButton:NO animated:YES];
return YES;
}