How process click button ios? - ios7

I have 3 view.view 0 (0,0,320,300),view 1 (0,300,320,300),view 2 (0,300,320,300)and 1 button.
view 0 doesn't change position.When I don't click button view 2 override view 1 but when I click button,I set position of view 2(0,600,320,300).I use auto layout on storyboard.
CODE
- (void)viewDidLoad
{
_contraintAfter = [NSLayoutConstraint constraintWithItem:_view1
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:_view2
attribute:NSLayoutAttributeTop
multiplier:1
constant:0];
_btnInfoView.selected = NO;
}
#pragma mark - Auto Layout
-(void)layoutInfoAppeare
{
[UIView animateWithDuration:0.5
animations:^{
[self.view removeConstraint:_contraintBefore];
[self.view addConstraint:_contraintAfter];
[self.view layoutIfNeeded];
}
completion:^(BOOL finished) {
_view1.hidden = NO;
}];
}
-(void)layoutInfoDisappeare
{
_view1.hidden = YES;
[UIView animateWithDuration:0.5
animations:^{
[self.view removeConstraint:_contraintAfter];
[self.view addConstraint:_contraintBefore];
[self.view layoutIfNeeded];
}];
}
and when i click button i process:
- (IBAction)btnVaccineOtherClick:(id)sender
{
UIButton *btn = (UIButton *)sender;
btn.selected = !btn.selected;
if (btn.selected) {
[self layoutInfoAppeare];
} else {`
[self layoutInfoDisappeare];
}
}
I don't understand,When I click button the first view 2 doesn't change position.But When I click the second view 2 change position.Can you help me?

Related

UIVIew animation is not working properly in iOS 10

The GIF shows the issue.
The below code display how I am adding view into superview and bringing up from bottom of superview. This code working fine in iOS 9 and not in iOS 10.
The animation of slide-up animation is not proper. It is coming out from right-side and making angle instead of straight from bottom.
Please help me to resolve this.
+ (ControlsView *)addArticleControlsToView:(UIView *)view bellowSubview:(UIView *)subview{
ControlsView *articleControls = [[[NSBundle mainBundle] loadNibNamed:#"ControlsView" owner:self options:nil]firstObject];
[view insertSubview:articleControls belowSubview:subview];
NSDictionary *viewsDict = #{#"currentView":articleControls};
[articleControls setTranslatesAutoresizingMaskIntoConstraints:NO];
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:[NSString stringWithFormat:#"H:|-0-[currentView]-0-|"] options:0 metrics:#{} views:viewsDict];
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"V:[currentView(189)]-0-|" options:0 metrics:#{} views:viewsDict];
[view addConstraints:horizontalConstraints];
[view addConstraints:verticalConstraints];
[articleControls setBackgroundColor:[UIColor clearColor]];
articleControls.viewBottomConstraint.constant = -189;
[articleControls layoutIfNeeded];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:articleControls action:#selector(slideSheetDown)];
[articleControls addGestureRecognizer:tapGesture];
return articleControls;
}
- (void)slideSheetUp {
[UIView animateWithDuration:0.5 animations:^{
self.viewBottomConstraint.constant = 0;
self.scrollViewBottomConstraint.constant = 189;
[self setBackgroundColor:[UIColor clearColor]];
[self.scrollView.superview layoutIfNeeded];
[self layoutIfNeeded];
}];
}
Just use this code
- (void)slideSheetUp {
self.viewBottomConstraint.constant = 0;
self.scrollViewBottomConstraint.constant = 189;
[self setBackgroundColor:[UIColor clearColor]];
[UIView animateWithDuration:0.5 animations:^{
[self.scrollView.superview layoutIfNeeded];
[self layoutIfNeeded];
}];
}
Hope it will works for you. ;)
Happy coding!!
Works for me.
-(void)hideShowTimerButton:(BOOL)show{
[UIView animateWithDuration:0.3 animations:^{
CGRect yourViewFrame = yourView.frame;
if(show){
timeContainerViewFrame.origin.y = self.view.frame.size.height;
}else{
timeContainerViewFrame.origin.y = self.view.frame.size.height - yourViewFrame.size.height;
}
yourView.frame = yourViewFrame;
} completion:^(BOOL finished) {
}];
}
Please re-arrange your code like below it has not affected my view animation too much and solved my problem. Thanks you guys.
- (void)slideSheetUp {
self.viewBottomConstraint.constant = 0;
[self setBackgroundColor:[UIColor clearColor]];
[UIView animateWithDuration:0.5 animations:^{
[self layoutIfNeeded];
} completion:^(BOOL finished) {
self.scrollViewBottomConstraint.constant = 189;
[self.scrollView.superview layoutIfNeeded];
}];
}

Animating a subview with CentreY constraint

I have a UITableViewCell with two UILabels and a UISwitch. The labels are multilined and placed on top of each other. The UISwitch is centred vertically. When I turn off the switch I hide one of the labels and the height of the row changes. This causes the switch to jump though I call:
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
Here is my tableviewcell class implementation:
- (void)setBounds:(CGRect)bounds
{
[super setBounds:bounds];
self.contentView.frame = self.bounds;
}
- (void)setUpView{
self.numberLabel.text = [NSString stringWithFormat:#"Quote number %ld", [self.cellData[#"rowNumber"] integerValue]];
[self.controlSwitch setOn:[self.cellData[#"checked"] boolValue]];
[UIView animateWithDuration:0.5 animations:^{
if ([self.controlSwitch isOn]) {
self.quoteLabel.text = self.cellData[#"quote"];
self.quoteLabel.hidden = NO;
self.bottomConst.constant = 10;
}else{
self.quoteLabel.text = #"";
self.quoteLabel.hidden = YES;
self.bottomConst.constant = 0;
}
}];
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self.contentView updateConstraintsIfNeeded];
[self.contentView layoutIfNeeded];
self.numberLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.numberLabel.frame);
self.quoteLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.quoteLabel.frame);
}
- (IBAction)removeQuote:(id)sender {
[self.delegate updateCell:self];
}
The constraint settings on the UITableViewCell looks like this.
When the switch is turned on, I'm simply unhide the Quote label and set the text.
Here is the link on how it looks like. Is this the default behavior or is there a way I can control the movement of the switch when the row animates?
Try this:
...
[self.contentView updateConstraintsIfNeeded];
[UIView beginAnimations:nil context:nil];
[self.contentView layoutIfNeeded];
[UIView commitAnimations];
...

UIView not animating correctly when UILabel is added to it

I'm animating a custom view off screen using a constraint on view's top edge.
The view is:
#implementation MyView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setBackgroundColor:[UIColor yellowColor]];
_label = [UILabel new];
[_label setTranslatesAutoresizingMaskIntoConstraints:NO];
_label.text = #"text";
[self addSubview:_label];
[self updateConstraints];
}
return self;
}
- (void)updateConstraints
{
NSDictionary *views = NSDictionaryOfVariableBindings(_label);
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-[_label]"
options:NSLayoutFormatAlignAllLeft
metrics:nil
views:views]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[_label]"
options:NSLayoutFormatAlignAllCenterY
metrics:nil
views:views]];
[super updateConstraints];
}
#end
The constraint for animating myView on its parent view is:
_myViewTopConstraint = [NSLayoutConstraint constraintWithItem:_myView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-kMyViewVisibleHeight];
[self.view addConstraint:_myViewTopConstraint];
The animation on the top edge constraint is:
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
self.myViewTopConstraint.constant = kScreenHeight;
[self.myView layoutIfNeeded];
} completion:nil];
When the label and constraints in MyView is commented out, the animation works perfectly. But when the label and constraints are there, the animation is sped up significantly, maybe 5x or more.
Why does this happen? Anyone know how to fix it?
Figured it out. layoutIfNeeded must be called on myView's parent view in the animation block.
[self.myView layoutIfNeeded];
changed to
[self.view layoutIfNeeded];

Hide UINavBar and UITabBar at the same time with animation

Edit: I awarded the bounty to john since he put a lot of effort into his answer, and would get it anyways, but there's still no working solution. I am still looking for an answer, if someone knows how to do this it'd be greatly appreciated.
I want to add a "maximize" button to my app that hides the navigation and tab bar. The navbar and tabbar should slide in/out smoothly, and the inner/content view should also expand and shrink at the same rate as the navbar and tabbar.
I used [self.navigationController setNavigationBarHidden: YES/NO animated: YES]; for the navbar and found this thread How to hide uitabbarcontroller for hiding the tabbar.
UITabBar class extension:
- (void) setTabBarHidden:(BOOL)hidden animated:(BOOL)animated {
CGRect screenRect = [[UIScreen mainScreen] bounds];
float screenHeight = screenRect.size.height;
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
screenHeight = screenRect.size.width;
}
if (!hidden) {
screenHeight -= self.tabBar.frame.size.height;
}
[UIView animateWithDuration: (animated ? UINavigationControllerHideShowBarDuration : 0) animations: ^{
for (UIView* each in self.view.subviews) {
if (each == self.tabBar) {
[each setFrame: CGRectMake(each.frame.origin.x, screenHeight, each.frame.size.width, each.frame.size.height)];
} else {
[each setFrame: CGRectMake(each.frame.origin.x, each.frame.origin.y, each.frame.size.width, screenHeight)];
}
}
} completion: ^(BOOL finished) {
NSLog(#"Animation finished %d", finished);
}];
}
The problem is when I use the two at the same time (hiding/showing the nav and tab bar), it's not clean. If the navbar comes first, anything anchored to the bottom jumps (see example below), and if the tabbar comes first, the top jumps.
Example: I position the UIButton in the bottom right and set its autoresizing mask
resizeButton.frame = CGRectMake(self.view.bounds.size.width - 50, self.view.bounds.size.height - 100, 32, 32); // hardcoded just for testing purposes
resizeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
But when the navbar and tabbar are minimized the UIButton jumps between the two states (doesn't slide along with the tab bar). However, if I change it to attach to the top right, it slides perfectly with the nav bar.
Does anyone know how to solve this?
Edit:
This is the closet and most elegant solution I have so far (just trying to get a working concept):
[UIView animateWithDuration: UINavigationControllerHideShowBarDuration animations: ^{
if (self.isMaximized) {
self.tabBarController.view.frame = CGRectMake(0, 20, screenRect.size.width, screenRect.size.height + 49 - 20);
[self.navigationController setNavigationBarHidden:YES animated:YES];
} else {
self.tabBarController.view.frame = CGRectMake(0, 20, screenRect.size.width, screenRect.size.height - 20);
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
} completion: ^(BOOL finished) {
NSLog(#"Frame done: %#", NSStringFromCGRect(self.view.frame));
return;
}];
On maximizing:
Slides the navbar up, and slides the tabbar down, at the same time
The top of the inner/content view slides up, and the bottom of this view jumps down
On minimizing:
Slides the navbar down, and slides the tabbar up, at the same time
The top of the inner/content view slides down properly, but the bottom jumps to the final value, leaving whitespace which is then covered by the sliding tabbar
If I rearange the order of the minimizing-animations (so the navbar animatino is called first), then the top in the inner/content view jumps
the solution i use should eliminate the jump problem you see.
this solution is derived from an Objective-C category found Carlos Oliva's github page, and while the copyright in that code is "all rights reserved", i wrote him and he provided permission for use.
my category code varies only slightly from his code. also, find below the category code the invocation code that i use in my app.
from UITabBarController+HideTabBar.m
// the self.view.frame.size.height can't be used directly in isTabBarHidden or
// in setTabBarHidden:animated: because the value may be the rect with a transform.
//
// further, an attempt to use CGSizeApplyAffineTransform() doesn't work because the
// value can produce a negative height.
// cf. http://lists.apple.com/archives/quartz-dev/2007/Aug/msg00047.html
//
// the crux is that CGRects are normalized, CGSizes are not.
- (BOOL)isTabBarHidden {
CGRect viewFrame = CGRectApplyAffineTransform(self.view.frame, self.view.transform);
CGRect tabBarFrame = self.tabBar.frame;
return tabBarFrame.origin.y >= viewFrame.size.height;
}
- (void)setTabBarHidden:(BOOL)hidden {
[self setTabBarHidden:hidden animated:NO];
}
- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated {
BOOL isHidden = self.tabBarHidden;
if (hidden == isHidden)
return;
UIView* transitionView = [self.view.subviews objectAtIndex:0];
if (!transitionView)
{
#if DEBUG
NSLog(#"could not get the container view!");
#endif
return;
}
CGRect viewFrame = CGRectApplyAffineTransform(self.view.frame, self.view.transform);
CGRect tabBarFrame = self.tabBar.frame;
CGRect containerFrame = transitionView.frame;
tabBarFrame.origin.y = viewFrame.size.height - (hidden ? 0 : tabBarFrame.size.height);
containerFrame.size.height = viewFrame.size.height - (hidden ? 0 : tabBarFrame.size.height);
[UIView animateWithDuration:kAnimationDuration
animations:^{
self.tabBar.frame = tabBarFrame;
transitionView.frame = containerFrame;
}
];
}
from my ScrollableDetailImageViewController.m
- (void)setBarsHidden:(BOOL)hidden animated:(BOOL)animated
{
[self setTabBarHidden:hidden animated:animated];
[self setStatusBarHidden:hidden animated:animated];
// must be performed after hiding/showing of statusBar
[self.navigationController setNavigationBarHidden:hidden animated:animated];
}
- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated
{
id parent = self.navigationController.parentViewController;
if ([parent respondsToSelector:#selector(isTabBarHidden)]
&& hidden != [parent isTabBarHidden]
&& [parent respondsToSelector:#selector(setTabBarHidden:animated:)])
[parent setTabBarHidden:hidden animated:animated];
}
Just try this code, If it is working. I have written this code a year before. But, still it works good for me.
I didn't used the block based animations. Because it was written when I am new to iOS. Just try and optimize yourself as you wanted.
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
[self.navigationController setNavigationBarHidden:YES animated:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.1];
for(UIView *view in tabbarcontroller.view.subviews)
{
if ([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}else if([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 1024, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 1024)];
}
}
}
[UIView commitAnimations];
}
// Method shows the bottom and top bars
- (void) showTabBar:(UITabBarController *) tabbarcontroller {
[self.navigationController setNavigationBarHidden:NO animated:YES];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.1];
for(UIView *view in tabbarcontroller.view.subviews)
{
if ([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 430, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 436)];
}
}else if([[UIDevice currentDevice]userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 975, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 980)];
}
}
}
[UIView commitAnimations];
}
Try this
you can hide tabbar contrller and navigation bar using animation like:-
-(IBAction)hide:(id)sender
{
[self hideShowBars];
}
- (void) hideShowBars
{
CGRect rect = self.navigationController.navigationBar.frame;
CGRect rect1 = self.tabBarController.tabBar.frame;
if(self.navigationController.navigationBar.isHidden)
{
[self.navigationController.navigationBar setHidden:NO];
rect.origin.y=self.view.frame.origin.y;
}
else
{
rect.origin.y=self.view.frame.origin.y-rect.size.height;
}
if(self.tabBarController.tabBar.isHidden)
{
[self.tabBarController.tabBar setHidden:NO];
rect1.origin.y=self.view.frame.size.height-rect1.size.height-rect1.size.height;
}
else
{
rect1.origin.y=self.view.frame.size.height;
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.50];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(hideShowBarsAnimationStopped)];
self.navigationController.navigationBar.frame=rect;
self.tabBarController.tabBar.frame = rect1;
[UIView commitAnimations];
}
- (void) hideShowBarsAnimationStopped
{
if(self.navigationController.navigationBar.frame.origin.y==self.view.frame.origin.y)
return;
if(!self.navigationController.navigationBar.isHidden)
{
[self.navigationController.navigationBar setHidden:YES];
}
if(!self.tabBarController.tabBar.isHidden)
{
[self.tabBarController.tabBar setHidden:YES];
}
}

Handling Device orientation problem for swapped views

i'm doing an ipad application, in which i have say two views
mainview and aboutus view
on startup i put the mainview in the rootcontroller's view (the one that is added to the window) alone.
and there's a button on mainview, that, when pressed, will remove the mainview from superview and put the aboutusview instead. aboutus has a similar button that gets us back to mainview.
Now the problem lies in the rotation (orientation).
when i detect an orientation change, i update the displayed view. works fine. (for mainview and aboutusview)
But if i rotate once any view, and then then try to see the second view. it seems that the second view is not autosizing.
CODE in rootViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
_currentOrientation=UIDeviceOrientationPortrait;
[self.view addSubview:_mainView];
[_splashView removeFromSuperview];
}
-(void)viewDidAppear:(BOOL)animated
{
_currentView = _mainView;
}
-(void)toggleMainPage
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:[self view] cache:YES];
[_infoView removeFromSuperview];
[self.view addSubview:_mainView];
_currentView=_mainView;
[self transformViewAccordingToOrientation:_currentOrientation];
[UIView commitAnimations];
}
-(void)toggleAboutPage
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:.5];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self view] cache:YES];
[_mainView removeFromSuperview];
[self.view addSubview:_infoView];
_currentView=_infoView;
[self transformViewAccordingToOrientation:_currentOrientation];
[UIView commitAnimations];
}
-(void) transformViewAccordingToOrientation:(UIDeviceOrientation)toInterfaceOrientation
{
if(toInterfaceOrientation == UIDeviceOrientationPortrait)
{
[_mainBtnCustom setBackgroundImage:[UIImage imageNamed:#"main.png"] forState:UIControlStateNormal];
_infoImage.image = [UIImage imageNamed:#"about.png"];
}else
{
[_mainBtnCustom setBackgroundImage:[UIImage imageNamed:#"mainr.png"] forState:UIControlStateNormal];
_infoImage.image = [UIImage imageNamed:#"aboutr.png"];
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self transformViewAccordingToOrientation:toInterfaceOrientation];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
_currentOrientation = [UIDevice currentDevice].orientation;
[self transformViewAccordingToOrientation:_currentOrientation];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (_currentOrientation !=interfaceOrientation);
}
what am i doing wrong?