UIButton Changing Position - ios

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.

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

UIScrollview as main view IOS 8

i'm trying to make a uiscrollview as main view in IOS 8 but i can't.
I have the following structure:
View
Header_View (Like TabBar)
UIScrollView
ContentView
UIImage
UILabel_Text
UIButton
Sometimes the text is bigger than others so i don't know the exactly height of the view. With this structure when i try to scroll vertical nothing happens.
Could someone help me?
Thanks.
First take a int variable like ajustHeight in ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : ViewController{
int ajustHeight;
}
then in ViewController.m use this variable to get UILabel_Text height like below.
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
UILabel *successlabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 215, 75)];
successlabel.text = message;
successlabel.numberOfLines = 0;
successlabel.textAlignment = NSTextAlignmentLeft;
[successlabel sizeToFit];
[expandableview addSubview:successlabel];
ajustHeight = successlabel.frame.size.height;
}
Now you get successlabel height after that you can adjust the view and scrollview content height as well. if you create UILable in for loop then user like ajustHeight += successlabel.frame.size.height;

Update the preferredMaxLayoutWidth for a multiline UILabel with unknown size (Auto Layout)

I have a custom view class which inherits from UIView. This class has an UILabel as its subview. In the init-function of this custom view class I set up everything needed like this:
//h-file
#import <UIKit/UIKit.h>
#interface MyCustomView : UIView
#property (strong, nonatomic) UILabel *myLabel;
#end
//m-file
#implementation MyCustomView
#synthesize myLabel = _myLabel;
- (id)init
{
self = [super init];
if (self) {
_myLabel = [UILabel new];
if(_textView){
_myLabel.highlightedTextColor = [UIColor whiteColor];
_myLabel.translatesAutoresizingMaskIntoConstraints = NO;
_myLabel.lineBreakMode = NSLineBreakByWordWrapping;
_myLabel.numberOfLines = 0;
_myLabel.backgroundColor = [UIColor clearColor];
[self addSubview:_myLabel];
}
}
return self;
}
#end
I also set up a bunch of constraints to manage padding inside my custom view - furthermore there are constraints to layout multiple MyCustomView-instances for both vertical and horizontal axis as well.
To get a multilined label output I have to set the preferredMaxLayoutWidth-property of the UILabel myLabel. The width depends on the free space available. At http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html I read, that I can let Auto Layout calculate the width first and set it as preferredMaxLayoutWidth after the frame of the MyCustomView-instance (the label inside is single lined at this moment) has been set.
If I put the following function into the MyCustomView, the label still has a single line of text:
- (void)layoutSubviews
{
[super layoutSubviews];
float width = _myLabel.frame.size.width;
_myLabel.preferredMaxLayoutWidth = width;
[super layoutSubviews];
}
If I set the preferredMaxLayoutWidth to an explicit value inside the init-function, the label is multilined.
Does anybody know what I am doing wrong here?
Thanks in advance!
Without seeing all the constrains you have setup for your custom view, and the superview that contains it, it's really hard to determine the problem, I suggest you to print out all the view frames of the entire view hierarchy starting from the view controller's view at viewDidLayoutSubviews and determine if the label and its superviews have correct frame set.
I have an encountered similar issues with dynamic label size and scroll view so I created a prototype here, might be useful to you too: https://github.com/briandotnet/AutoLayoutScrollViewExperiment

UIImageView not correctly updating bounds

I am currently trying to program a game with a HP gauge represented by an UIImageView placed on a .xib file. I declared my IBOutlet as follows:
#property (weak, nonatomic) IBOutlet UIImageView *hpGaugeView;
and synthesized accordingly. It is also linked to the UIImageView instance in the xib.
In the xib, I set the length of hpGaugeView to 188 and height to 9.
Now this is what I did in viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[hpGaugeView setFrame:CGRectMake(49, 18, 123, 9)];
NSLog(#"%f, %f", [hpGaugeView frame].size.width, [hpGaugeView frame].size.height);
}
Although NSLog tells me the hpGaugeView's width is 123, when I run it the length appears unchanged compared to the one in xib. All the other setFrame: or setBound: worked fine in other viewControllers, so I'm just wondering what's happening here.
It is a small but crucial problem that is bugging me for a few hours straight...
Edit:
When I turn off AutoLayout, the resizing worked; it creates a bunch of other problems though...
With autolayout on, the subviews have not been laid during the viewDidLoad. The constraints are calculated a bit later and you can override the viewDidLayoutSubviews method to set your frame:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// Do any additional setup after subviews are laid.
[hpGaugeView setFrame:CGRectMake(49, 18, 123, 9)];
NSLog(#"%f, %f", [hpGaugeView frame].size.width, [hpGaugeView frame].size.height);
}
From the class reference:
viewDidLayoutSubviews
Notifies the view controller that its view just laid out its subviews.
I believe the problem is that you're not changing the frame of the UIImageView. The bounds refer to the position and size of the view in it's own coordinate system whereas the frame refers to the position and size in it's superview coordinate system.
If the clipsToBounds property is set yo YES, then nothing outside the frame of your view will be visible.
It turns out it is some weird weird interaction between the nib and the code...when I created the UIImageView programmatically it worked fine.
AutoLayout property worked only above IOS 6.0 only . Dragging of control to XIB instead of you can create the UIImageView through Code and add to current view. I have given the code for adding UIImageView programmatically.
Source Code:
// .h file
#property (weak, nonatomic) UIImageView *hpGaugeView;
//.m file
- (void)viewDidLoad
{
[super viewDidLoad];
hpGaugeView = [[UIImageView alloc] init];
[hpGaugeView setFrame:CGRectMake(49, 18, 123, 9)];
[self.view addSubview:hpGaugeView];
}
Initialize and add the hpGaugeView to subview inside the viewDidLoad function through programmatically.

sizeToFit and constraints

I have an view:
There is layout constraint between label1 and label2. Pressing on button adds text from text view to label1. After it label 1 is resized to fit text (sizeToFit is called). And after resizing it looks like constraints don't work:
Does somebody has an idea how to make constraints work?
My coode:
#interface ViewController ()
{
CGFloat _width;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void) viewDidAppear:(BOOL)animated
{
_width = self.l1.frame.size.width;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)addText:(id)sender {
self.l1.text = [NSString stringWithFormat:#"%# %#", self.l1.text, self.text.text];
self.l1.frame = CGRectMake(self.l1.frame.origin.x, self.l1.frame.origin.y, _width, 0);
[self.l1 sizeToFit];
}
#end
I've found the reason: height constraint was equal to 40 of label 1. When I change it to greater or equal , all other constraints work ok.
I had a similar issue in which an UIImageView was at the top of several UILabelViews. The constraints were set to keep a small distance between the top image and the stack of labels below.
The problem was that when loading an unknown image size into the UIImage the height would change, but the labels to follow did not push down, and were covered by the image.
I tried to delete the set height of the UIImageView but XCode would not let me.
I resolved the issue by reducing the priority on the explicit UIImageview height constraint to 1.
After, the labels moved down the ViewController with even space between the image and themselves, as expected.

Resources