How to add a view behind other view in iOS - iphone

I want to add a view under my tab bar analog in iOS and then show it with animation coming from behind it. But when I use my code, the view that must come from behind my tab bar overlaps my tab bar for a while.
This is my code:
- (void)handlePressedButton {
if (pressedButton.selected) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
CGAffineTransform transform1 = CGAffineTransformMakeTranslation(-196.0, 0.0);
CGAffineTransform transform2 = CGAffineTransformMakeTranslation(0.0, 0.0);
[leftPanelView setTransform:transform1];
[movedView setTransform:transform2];
[UIView commitAnimations];
pressedButton.selected = NO;
}
else {
pressedButton.selected = YES;
if (leftPanelView) {
[leftPanelView removeFromSuperview];
leftPanelView = nil;
}
CGRect viewFrame = CGRectMake(-196, 0, 236, 748);
leftPanelView = [[UIView alloc] initWithFrame:viewFrame];
leftPanelView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"left-nav-content.png"]];
// Code to populate leftPanelView according to what button is pressed.
[self populateLeftPanelView];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[self.view addSubview:leftPanelView];
CGAffineTransform transform1 = CGAffineTransformMakeTranslation(236.0, 0.0);
CGAffineTransform transform2 = CGAffineTransformMakeTranslation(112.0, 0.0);
[leftPanelView setTransform:transform1];
[movedView setTransform:transform2];
[UIView commitAnimations];
}
}
Here the leftPanelView is the view that must come under a tab bar. Moved view is another view, that is at the right of left panel (don't mind it)

Besides addSubview, there are other methods you can rely on to add your view:
– insertSubview:aboveSubview:
– insertSubview:belowSubview:
– insertSubview:atIndex:
You can control the index (actually z-index, or layer order) of the view using these methods.

try sendSubviewToBack
[self.view sendSubviewToBack:leftPanelView];

Swift 5
Insert a view below another view in the view hierarchy:
view.insertSubview(subview1, belowSubview: subview2)
Insert a view above another view in the view hierarchy:
view.insertSubview(subview1, aboveSubview: subview2)
Insert a subview at the specified index:
view.insertSubview(subview, at: index)
Move the specified subview so that it appears behind its siblings:
subview1.sendSubviewToBack(subview2)
Move the specified subview so that it appears on top of its siblings:
subview1.bringSubviewToFront(subview2)
Exchange the subviews at the specified indices:
view.exchangeSubview(at: index1, withSubviewAt: index2)

Oh, I found a solution myself. I added after this:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[self.view addSubview:leftPanelView];
this line:
[self.view sendSubviewToBack:leftPanelView];

In Swift 5
self.view.sendSubviewToBack(leftPanelView)

Another nice idea is to give the Subviews a tag.
Swift
mainView.addSubView(topView)
mainView.addSubView(bottomView)
topView.tag = 2
mainView.insertSubview(bottomView, belowSubview: mainView.viewWithTag(2))

Objective-C
Insert a view below another view in the view hierarchy:
- (void)insertSubview:(UIView *)subview1
belowSubview:(UIView *)subview2;
Insert a view above another view in the view hierarchy:
- (void)insertSubview:(UIView *)subview1
aboveSubview:(UIView *)subview2;
Insert a subview at the specified index:
- (void)insertSubview:(UIView *)view
atIndex:(NSInteger)index;
Move the specified subview so that it appears behind its siblings:
- (void)sendSubviewToBack:(UIView *)view;
Move the specified subview so that it appears on top of its siblings:
- (void)bringSubviewToFront:(UIView *)view;
Exchange the subviews at the specified indices:
- (void)exchangeSubviewAtIndex:(NSInteger)index1
withSubviewAtIndex:(NSInteger)index2;

Related

Animate a UIView change where the UIView is totally rebuilt

My UIViewController gets the view it is controlling to completely rebuild itself with something like this:
[self.view rebuildYourself:bIsLandscape]; // this line is in the ViewController
The view itself then contains the following method:
-(void)rebuildYourself:(BOOL)isLandscape
{
NSArray *viewsToRemove = [self subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
[self addControls]; // adds lots of views
[self layoutControlsWithOrientation:isLandscape]; // frames the views
}
I would like to animate the entire transition. I have tried this:
[UIView animateWithDuration:1.0
delay:0.0
options:UIViewAnimationOptionTransitionCurlUp
animations:^{
[self.view rebuildYourself:bIsLandscape];
}
completion:^(BOOL finished){
}];
but the animation ignores the options value of UIViewAnimationOptionTransitionCurlUp and flows in from the top left corner every time.
and I have tried this:
[UIView beginAnimations:#"kkk" context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
[UIView setAnimationDuration:1.0];
[self.view rebuildYourself:bIsLandscape];
[UIView commitAnimations];
but in this case the transition does curl up nicely but the underlying view is blank until the transition has finished, and then the new view suddenly 'pops' into view, which spoils the effect of the transition.
Can anyone tell me the right/best way to animate a transition where the view rebuilds itself completely?
Thanks
Make two views and put the old view overtop of the new re-built view. Then 'Curl-up' the old view so that the new view is showing and remove the old view from memory.

how i can move label over all view

My view layout http://i.imgur.com/PkZ9P.png
-(IBAction)tapview:(id)sender
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:1];
CGRect frame = labelgreen.frame;
frame.origin.y -= 200;
labelgreen.frame = frame;
[UIView setAnimationDidStopSelector:#selector(forview1)];
[UIView commitAnimations]; }
but when label move it move only inside view1 or view2 or view 3,
i would like to let it move over all view to color view
what i should do?
and after animation finish it should run function -(void)forview1
but the function is not call
-(void)forview1
{colorview.backgroundcolor=changecolor;}
thank you
Spelling mistake in ur function
NOT
[UIView setAnimationDidStopSelector:#selector(foeview1)];
//correct
[UIView setAnimationDidStopSelector:#selector(forview1)];
more over
replace this line
labelgreen.frame.frame = frame;
To
labelgreen.frame = frame;
declare this function in ur .h
-(void)forview1;
First, try to replace
[UIView setAnimationDidStopSelector:#selector(foeview1)];
with
[UIView setAnimationDidStopSelector:#selector(forview1)];
Second, push label on the top of views using following method
- (void)bringSubviewToFront:(UIView *)view
For example:
UILabel * labelgreen;
[labelgreen.superview bringSubviewToFront:labelgreen];
If you are creating this view in IB then just drag UILabel to the bottom of its subviews.
You should use block based animations. Those functions are deprecated.
[UIView animateWithDuration:animationDuration animations:^{
}];
The label views are nested inside View1/View2/View3 and thus are clipped to the bounds of those containing views. To make them move around the outer view you will need to either start them off in the main view, or before starting the animation remove them from the containing views and add them to the outer view. You could also look into whether the clipToBounds property can be used to have the label views render when they are moved out of the bounds of their containing view.
Example of removing and re-adding in containing view (assuming the labelgreen view is inside a view called view2) (do this before you start your animation).
CGRect newframe = labelgreen.frame
newframe.origin.y = newframe + view2.frame.origin.y;
newframe.origin.x = newframe + view2.frame.origin.x;
[labelgreen removeFromSuperview];
labelgreen.frame = newframe;
Then either:
[colorview addSubview:labelgreen]; // (assuming colorview is your main containing view).
Or:
[self.view addSubview:labelgreen]; // if self.view is the main containing view

Fade to black within a uinavigationcontroller?

I want to fade the whole screen (including navigation bar) to black when a user presses a button on a uinavigationcontroler, before showing a new view. (i don't want to push this new view, for various reasons).
How would I achieve this?
EDIT
Thanks to Mac and Eiko, I have figured it out. Here's the code I used. Not sure if it is optimal, but it does the trick.
// this is called from a programmatically constructed button.
// change (void) to (IBAction) if linking from IB.
- (void)fadeAndShow:(id)sender
{
// blackView is a #property which has been #synthesize-d
// do I really need to alloc and init this?
blackView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
blackView.alpha = 0.0;
[blackView setBackgroundColor:[UIColor blackColor]];
[self.navigationController.navigationBar.superview addSubview:blackView];
[UIView beginAnimations:#"fadeAway" context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDidStopSelector:#selector(showNewScreen:finished:context:)];
blackView.alpha = 1.0;
[UIView commitAnimations];
}
-(void)showNewScreen:(NSString *)animationID finished:(BOOL)finished context:(void *)context
{
// I guess you could fade in somewhere in the new view controller.
// don't know how to fade back in this view tho... viewDidAppear?
NewViewController *controller = [[NewViewController alloc] initWithNibName:#"NewView" bundle:nil];
[self.navigationController setNavigationBarHidden:YES];
controller.hidesBottomBarWhenPushed = YES;
[[self navigationController] pushViewController:controller animated:NO];
[blackView removeFromSuperview];
[controller release];
}
Off the top of my head (I haven't actually tested the following at all):
-(IBAction) buttonClicked:(id) sender
{
[UIView beginAnimations:#"myAnimation" context:nil];
[UIView setAnimationDuration:ANIMATION_DURATION];
blackView.alpha = 1.0;
[UIView commitAnimations];
}
Create a UIView in the navigationbar's superview (which I'm assuming is window-sized) that is the same size as the window.
Set that view's backgroundColor to [UIColor blackColor], and its alpha to 0.0.
In your button handler do something like the above (assuming your new UIView is blackView and ANIMATION_DURATION is your desired animation time in seconds).
Then, add your new view on top.
EDIT: too quick for me Eiko! Also, code at the top since the ordered list seems to screw around with the code formatting - sorry the answer reads a little odd.
You can add a black coloured UIView in screen size on top of your current view, and animate its alpha from 0 to 1. When the animation is done, add your new view. You can remove the black one then. Animate from 1 to 0 for the opposite effect - going from black to the content).

iPhone UIView Question. How to get notified when a UIView becomes completely hidden?

I have a have a strip of UIViews that slides horizontally behind a UIView "window". Only the UIViews within the bounds of the "window" are seen. As a view becomes hidden I would like to be notified so that I can perform some task with the just hidden view. What is the best way to do this?
In your UIScrollViewDelegate:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// left and right bounds of the subview in relation to the scrollview
CGFloat left = mySubview.frame.origin.x - myScrollView.contentOffset.x;
CGFloat right = left+mySubview.frame.size.width - myScrollView.contentOffset.x;
if(right<=0 || left>=myScrollView.frame.size.width){
// The view is not visible
}
}
this checks if either the left or right side of the subview is visible.
Add a callback selector to your animation:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:theView cache:NO];
[UIView setAnimationDidStopSelector:#selector(animationDone)];
theView.frame = newFrame;
[UIView commitAnimations];

Flip View Iphone

please consider the code below, and tell me what I'm doing wrong.
I want to flip between two UIViews.
Somehow, when I flip away from the initial view, I just get the flipped view, without animation. When I flip back, the animation shows just fine.
The flips are triggered from buttons on the views themselves.
- (IBAction)showMoreInfo:(id)sender
{
UIView *moreInfo = self.flipView;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
UIView *parent = self.view.superview;
[self.view removeFromSuperview];
[parent addSubview:moreInfo];
[UIView commitAnimations];
}
- (IBAction)showLessInfo:(id)sender
{
UIView *lessInfo = self.view;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0];
[UIView setAnimationBeginsFromCurrentState:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.flipView cache:YES];
UIView *parent = self.flipView.superview;
[self.flipView removeFromSuperview];
[parent addSubview:lessInfo];
[UIView commitAnimations];
}
It's probably because you aren't using a container view as the transition view. Refer to the documentation on setAnimationTransition:forView:cache:
If you want to change the appearance of a view during a transition—for example, flip from one view to another—then use a container view, an instance of UIView, as follows:
Begin an animation block.
Set the transition on the container view.
Remove the subview from the container view.
Add the new subview to the container view.
Commit the animation block.
Try using self.view.superview in the animation transition view of the showMoreInfo:
The reason the showLessInfo: method works is you are using a container view.
Can you use your MainWindow (UIWindow) as the container view as UIWindow inherence from UIView?
Also iPhone 3.0 introduced the flip transaction via the presentModalViewController method:
CustomViewController *vc = [[CustomViewController alloc]
initWithNibName:#"CustomViewController" bundle:nil];
vc.delegate = self;
// The magic statement. This will flip from right to left.
// present the modal view controller then when you dismissModalViewController
// it will transition flip from left to right. Simple and elegant.
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:vc animated:YES];
[vc release];
After iOS 4.0, you can flip between views with this:
[UIView transitionFromView:sourceView toView:destinationView duration:0.35f options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL finished) {
NSLog(#"I just flipped!");
}];
As Jason mentioned, you'll need this to occur within a container view.