How can I resize UIView width when some view hidden? - ios

The above Image is captured from storyboard.
It is constructed like as follows:
UIView (include UILabel and UIProgressView) <--2px spacing --> UIActivityIndicatorView <---6px spacing ---> UIButton
I want the UIView to increase its width to button when UIActivityIndicatorView hidden as follows:
UIView( include UILabel and UIProgressView) <---6 space---> UIButton
How can I do that?? Let me Know. Please.

https://github.com/bilobatum/ActivityIndicatorDemo
Make the button's intrinsic content size along the horizontal axis required (i.e., priority 1000). This prevents the layout from being ambiguous along the horizontal axis.
#interface ViewController ()
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *activityIndicatorWidthConstraint;
#property (strong, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
// spacerConstraint is the horizontal spacer constraint between the activity indicator and the gray view
#property (strong, nonatomic) IBOutlet NSLayoutConstraint *spacerConstraint;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.activityIndicator startAnimating];
}
- (IBAction)stopButtonTapped:(UIButton *)sender
{
sender.enabled = NO;
self.activityIndicatorWidthConstraint.constant = 0;
self.spacerConstraint.constant = 0;
[UIView animateWithDuration:1.0 animations:^{
self.activityIndicator.alpha = 0.0;
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
[self.activityIndicator stopAnimating];
//[NSLayoutConstraint reportAmbiguity:nil];
}];
}
#end

If you are using Auto-layout, consider setting the width of the UIActivityIndicatorView to 0 when you disable it. This won't be exactly what you need, but it's close.

Let's assume that your UILabel is called _label, UIProgressView is called _progressView and UIActivityIndicator is called _activityIndicator.
When you hide your _activityIndicator, call this block of code:
[_label setFrame:CGRectMake(_label.frame.origin.x, _label.frame.origin.y, _label.frame.size.width + _activityIndicator.frame.size.width + 2, _label.frame.size.height)];
[_progressView setFrame:CGRectMake(_progressView.frame.origin.x, _progressView.frame.origin.y, _progressView.frame.size.width + _activityIndicator.frame.size.width + 2, _progressView.frame.size.height)];
When _activityIndicator shows again:
[_label setFrame:CGRectMake(_label.frame.origin.x, _label.frame.origin.y, _label.frame.size.width - _activityIndicator.frame.size.width - 2, _label.frame.size.height)];
[_progressView setFrame:CGRectMake(_progressView.frame.origin.x, _progressView.frame.origin.y, _progressView.frame.size.width - _activityIndicator.frame.size.width - 2, _progressView.frame.size.height)];
Remember, that Autolayout should be turned off, if you want to manually set the frames! It is very simple: just uncheck the "Use Autolayout" feature in File Inspector:

Related

Change height of view programmatically in uistackview

I need to change the view height in the stack view when I press the test button, but it is not working properly.
When I press the test button, I want to set the height of view 3 to 50 and the height of view5 to fill the remaining area. When I press the test button again, i want to reverse to process. How can I do that?
Thank you.
As #SeanLintern88 mentioned, the way you really should be doing this is with auto layout constraints -- you don't want to be mixing setFrame with autolayout.
IBOutlet the height constraints for View 3 and View 5. Set the View 3 height constraint as inactive to start (if you want it to look like your storyboard does currently to start), then whenever the button is pressed, check which constraint is active and flip-flop them.
#import "ViewController.h"
#interface ViewController ()
#property (strong, nullable) IBOutlet NSLayoutConstraint *view3HeightConstraint;
#property (strong, nullable) IBOutlet NSLayoutConstraint *view5HeightConstraint;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// start us out as inactive
self.view3HeightConstraint.active = NO;
}
- (IBAction)btnPressed:(id)sender {
if (self.view5HeightConstraint.active) {
// view 5 height constraint is active
// you can set the height constants directly in storyboard as well
self.view3HeightConstraint.constant = 50.0f;
self.view3HeightConstraint.active = YES;
self.view5HeightConstraint.active = NO;
} else {
// view 3 is height constraint is active
// you can set the height constants directly in storyboard as well
self.view5HeightConstraint.constant = 50.0f;
self.view5HeightConstraint.active = YES;
self.view3HeightConstraint.active = NO;
}
// animate the layoutIfNeeded so we can get a smooth animation transition
[UIView animateWithDuration:1.0f animations:^{
[self.view layoutIfNeeded];
}];
}
#end

HidesBottomBarOnPush iOS10 safe area pinning issue

I'm having an issue with the safe area on iOS 10 where I trigger a segue to a view controller with hidesBottomBarOnPush enabled. The content which is pinned to the bottom safe area on this view controller starts off above the tabs then jumps to the bottom once the view has fully loaded.
How do I avoid this behaviour on iOS 10? Pinning to superview is not an option as iPhone X support is required.
Constraints on the label:
Pinning to superview, bind to the attribute, like this
#interface YourViewController ()
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraint;
#end
#implementation YourViewController
- (void)viewDidLoad {
[super viewDidLoad];
CGFloat bottomValue = 0.0f; // your value
UIEdgeInsets edgeInsets = UIApplication.sharedApplication.keyWindow.layoutMargins;
CGFloat bottomInset = edgeInsets.bottom;
self.bottomConstraint.constant = - bottomInset - bottomValue;
}
#end

Ios Animation of UIImageView with Constraints

I have an UIImageView which I placed in the center of screen using Align Center X and Align Center Y constraints.I want the image to move with animation to the top of screen keep the horizontal alignment in container and have a space of 20 from the top when i press a button. Remove the Align Center Y constraint programmatically and add the top space constraint is a good approach for that?
Calculate dynamically the constant with the UIScreen class and your view height.
#interface ViewController : UIViewController
#property (nonatomic, weak) IBOutlet NSLayoutConstraint *centerYConstraint;
#property (nonatomic, weak) IBOutlet UIView *myView;
- (IBAction)moveView:(id)sender;
#end
- (IBAction)moveView:(id)sender
{
self.centerYConstraint.constant = 20.0 + (self.myView.frame.size.height * 0.5) - ([UIScreen mainScreen].bounds.size.height * 0.5);
[UIView animateWithDuration:1.0 animations:^{
[self.view layoutIfNeeded];
}];
}
You can download the code here (http://cl.ly/3l1B0k1L0h1C)

iOS: Set View Size in Code with Autolayout enabled

I have two view controllers inside a tab bar navigation. Inside the second scene I have an additional view (just a simple UIView) and a button to set it's color and bounds.
CGRect viewRect = CGRectMake(20, 20, 70, 70);
self.animationView.bounds = viewRect;
self.animationView.backgroundColor =
[UIColor yellowColor];
This code works fine. But if I navigate to the first view controller and then back to the second view controller my view is still yellow but it is back at the size and position I set in interface builder.
How can I prevent this?
This behavior ends if I disable autolayout but I don't really want to do that.
Create outlets for the animationView constraints, and change their constant value.
In the .h file of the viewcontroller:
Connect the outlets to the correct constraint in the IB:
//AnimationView Height Constraint
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *cHeight;
//AnimationView Width Constraint
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *cWidth;
//AnimationView Leading Constraint
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *cLeading;
//AnimationView Top Constraint
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *cTop;
In the .m file of the ViewController set the constant value of the constraints, instead of the frame:
- (IBAction)btnTouched:(id)sender {
[_cHeight setConstant:70];
[_cWidth setConstant:70];
[_cTop setConstant:20];
[_cLeading setConstant:20];
self.animationView.backgroundColor = [UIColor yellowColor];
}
It'll work fine.

UIButton Changing Position

I have a button set up in IB. I have an IBOutlet set up and the onscreen object linked to it. Is there a way to programmatically change that buttons position and/or size? I know you can change the title and some things but I don't see how to change it's position or size.
Now I would like to change the position of it accordingly. Is it possible? If yes, please let me know how, since I am trying to change the position of my button in the following code, but it does not work in the header file.
#property (nonatomic, strong) IBOutlet UIButton *mybuttonOutlet;
In the implementation file:
-(void)viewDidLoad {
screenSizeHeight=[UIScreen mainScreen].bounds.size.height;
if(screenSizeHeight==568)
mybuttonOutlet.frame= CGRect(38, 464 ,157,25);
if(screenSizeHeight==480)
mybuttonOutlet.frame= CGRect(38, 364 ,157,25);
}
Remove Use Autolayout from the button in IB or storyboard.
If you want to adjust positions with Autolayout enabled, you will have to change your code like this
-(void)viewDidLayoutSubviews {
screenSizeHeight=[UIScreen mainScreen].bounds.size.height;
if(screenSizeHeight==568)
mybuttonOutlet.frame= CGRect(38, 464 ,157,25);
if(screenSizeHeight==480)
mybuttonOutlet.frame= CGRect(38, 364 ,157,25);
}
Basically you need to perform any custom layout adjustments in viewDidLayoutSubviews method if Autolayout is enabled
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#end
#import "ViewController.h"
#interface ViewController ()
#property(nonatomic, strong) IBOutlet UIButton *theButton;
// -(IBAction)moveTheButton:(id)sender;
#end
#implementation ViewController
#synthesize theButton;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)moveTheButton:(id)sender{
//set default position
CGRect btFrame = theButton.frame;
btFrame.origin.x = 145;
btFrame.origin.y = 285;
theButton.frame = btFrame;
//position changing
btFrame.origin.x += 40;
theButton.frame = btFrame;
//new size of button
CGRect rect=CGRectMake(145, 285, 190, 30);
[self.theButton setBounds:rect];
}
#end
I eventually went for the constraints. Get an outlet of the constraints that determine the position of the button (top, bottom, leading, trailing) and change the constraint(s) value(s).
self.constBtnSubmitTrailing.constraint = 50.0
This so you can keep AutoLayout enabled.
The solution I figured out for this is to create new View object inside the main View, and put my "dynamically changing objects" inside that View (as shown in picture).
Object hierarchy
Then I use Auto-Layout to position the new View in the main View.
But bugButton:UIButton which is inside the new View, changes position as expected with:
bugButton.frame.origin = CGPoint(x: newX, y: newY)
Please perform this check.
-(void)viewDidLoad{
if(self.mybuttonOutlet==nil)NSLog(#"Button is NIL");
}
Now if you get the log "Button is NIL", then probably you forgot to link your IB button to your variable mybuttonOutlet.

Resources