Unable to change height of UIView loaded from nib - ios

I have a view that is loaded from a nib like so:
SLSCaseCard* caseCard = [[[NSBundle mainBundle] loadNibNamed:#"SLSCaseCard" owner:self options:nil] objectAtIndex:0];
I'm setting it's frame like this:
cardFrame = CGRectMake(25,25, caseCard.frame.size.width, 44);
[caseCard setFrame:cardFrame];
[self.view addSubview:caseCard];
The x and y are changing but the height always remains the same. The view has a size of 224 in the nib, and it stays at that height at runtime.

Storyboard (or XIB's) generates code for you. And this code is executed in laying out subviews. So if you want to change frame of a view defined in XIB, you should do that after viewDidLayoutSubviews or layoutSubviews.
Hence even after you setting the height of the view, your changes are overridden by the code generated by XIB, which overrides the height to the height defined in XIB, in your case 224. Same goes with width.

Related

load views from xib, and how to change views' frame?

I load a view from a nib, this view has several subviews,and are on the xib.
Once I load this view from nib, I tried to change the subviews frame by using: view.subLabel.frame = CGRectMake(). However, this does not work and I do not know why. I disabled the autolayout property of the xib and it does not work as well. Anyone knows how to change views frame loaded from xibs? Thank you.
codes for init and change frame are as follows:
Init:
GADNativeContentAdView *adView = [[[NSBundle mainBundle] loadNibNamed:#"loadingContent" owner:nil options:nil] firstObject];
Then change frame:
adView.logoView.frame = CGRectMake(0, 0,50, 50);
but this does not work.
You should work with NSAutolayout and use NSAutoLayoutConstraints if you want to change the size or position of your subviews. For example declare a height constraint as a property, connect it in your xib, and change it this way:
myHeightConstraint.constant = newValue
UIView.animateWithDuration(duration, animations: {
self.view.layoutIfNeeded()
})
user2053760,
When you instantiate a view using
GADNativeContentAdView *adView = [[[NSBundle mainBundle] loadNibNamed:#"loadingContent" owner:nil options:nil] firstObject];
you havent specified its frame so by default it is instantiated with frame (0,0,0,0). Then you went on to change the view which is inside this adView and set its frame to (0,0,50,50).
How do you expect the subView to be visible if the view which holds it itself is of size (0,0) ???
so first change the parent frame as
adView.frame = CGRectMake(0, 0,50, 50);
then you can set the frame for childView,
adView.logoView.frame = CGRectMake(0, 0,50, 50);
try add the code:
[view setAutoresizesSubviews:NO];
Swift:
view.autoresizesSubviews = false

Xcode Custom view constraints not updating when updating size programmatically

I have a custom UIView that has 2 UILabel's which I have designed in the XIB. Have set the correct constraints to the sub items making them right aligned etc. In the XIB, my desgin was based on the assumption that screen width is 200 and constraints of the 2 labels are set to their superview accordingly.
-(id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[[NSBundle mainBundle] loadNibNamed:#"MyCustomView" owner:self options:nil];
[self addSubview:self.view];
//_intrinsicContentSize = self.bounds.size; // tried to return this as well
}
return self;
}
Now I programmatically alloc this view and and add it as subview to my view controller. If I change the frame of the view to say 300, the sub view frame gets changed to 300 but the 2 labels which have constraints follow a width of 200 only.
vewOneTouch = [[OneTouchView alloc] initWithFrame:CGRectMake(0, CGRectGetMinY(vewBottom.frame)-50, CGRectGetWidth(scwBaseView.frame), 50)];
[scwBaseView addSubview:vewOneTouch];
When the custom view frame is changed, why are the constraints not kicking in and changing the layout of all the items in the subview?
The white area is the yellow view in the Xib, have changed the color programmatically.

Progress View with UIView indicator

Hi guys i'm stuck with this problem. I need to create a behavior like this one in the image.
I created a UIView xib (because i need to reuse this view) with a UIProgressView for the 'dark orange' fill and then create an UIView for the indicator with a UILabel in it but i'm unable to move it with setFrame so i was thinking that subclassing an UISlider would be much easier.
What do you think?
This is the code that doesn't work, the .xib uses AutoLayout and now i'm using Xcode 6.
ScoresView *score = [[[NSBundle mainBundle] loadNibNamed:#"scoresView" owner:self options:nil] objectAtIndex:0];
[score.markView setFrame:CGRectMake(score.markView.frame.origin.x + offset, score.markView.frame.origin.y, score.markView.frame.size.width, score.markView.frame.size.height)];
[score.progressView setProgress:0.5];
[score setFrame:viewSize];
[self.scoreScrollView addSubview:score];
Since the views are using auto layout, you must animate the layout constraints, not the frame. You do that by creating an outlet to the constraint and changing its constant.
But it might be easier to not use auto layout on the dark orange view. Build and add it in code. Set its frame origin equal to the light orange view, and set its width equal to progress (0-1) * light orange width.

Resize imageview in its frame

I am trying to create a view that has 4 children
1 imageview
3 labels
The ImageView is supposed to take up the entire frame, and it doesnt
I've added layout constraints to it so that it would adjust to the sides.
However, i am initiating the view with different frames, and the image view size doesnt change
How do i make the image take up the entire purple area, of which it is a subview?
This is my xib file:
and this is how it looks on the device screen
the purple view is the frame i allocated for the given view:
and the green view is the entire screen
my init code:
NSArray *topViews = [[NSBundle mainBundle]loadNibNamed:#"BagView" owner:self options:nil];
[self addSubview:topViews[0]];
[self.shoppingBag setFrame:self.bounds];
NSArray *topViews = [[NSBundle mainBundle]loadNibNamed:#"BagView" owner:self options:nil];
UIView *v = topViews[0];
v.frame = self.bounds;
[self addSubview:v];
fixed the problem
Set the contentMode property of UIIMageView to UIViewContentModeScaleToFill
[your_imageview setContentMode: UIViewContentModeScaleToFill];

Loaded UIView from NIB - Wrong Frame Size

Ok, so I've created a UIView in interface builder. I'm using AutoLayout and I've got one subview of this view pinned to all four sides.
Here's what I don't understand. When I load this NIB file using loadNibNamed. I then get a reference to the view. I set the frame for this view. And yet, when I access the subview (using [containerView viewWithTag:1]) it's frame hasn't been automatically resized. What gives? If you change the frame for a parent view, why wouldn't the subview frame change as well?
It doesn't make any sense.
Why can't you just load a UIView, set it's frame and have all the subviews adjust as appropriate (ESPECIALLY since I'm using AutoLayout!)?
EDIT: To be clear, all I want to do is be able to define a UIView hierarchy in IB with appropriate AutoLayout constraints and then be able to load and display that view on the screen sometimes at different sizes? Why is this so hard?
UIKit doesn't update subview geometry immediately when you change a view's geometry. It batches up the updates for efficiency.
After running your event handler, UIKit checks whether any views in the on-screen window hierarchy need to be laid out. If it finds any, it lays them out by solving your layout constraints (if you have any) and then sending layoutSubviews.
If you want to solve the constraints and lay out a view's subviews immediately, simply send layoutIfNeeded to the view:
someView.frame = CGRectMake(0, 0, 200, 300);
[someView layoutIfNeeded];
// The frames of someView.subviews are now up-to-date.
I too had the same problem, I was creating a tutorial view where in which I wanted to add multiple UIViews to a scrollview. While I was trying to get the frame from xib, it gave always 320 and because of that the offset for the pages were wrong and my views looked crappy in iPhone6 and 6plus.
I then used pure autolayout approach, ie instead of using the frame, I added constraints through VFL so that subviews fit exactly to the superview. Below is the snapshot of code where I create around 20 UIViews from Xib and add properly to scrollview
Full code here ScrollViewAutolayout
Method to layout the childviews in the scrollview.
#param nil
#result layout the child views
*/
-(void)layoutViews
{
NSMutableString *horizontalString = [NSMutableString string];
// Keep the start of the horizontal constraint
[horizontalString appendString:#"H:|"];
for (int i=0; i<viewsArray.count; i++) {
// Here I am providing the index of the array as the view name key in the dictionary
[viewsDict setObject:viewsArray[i] forKey:[NSString stringWithFormat:#"v%d",i]];
// Since we are having only one view vertically, then we need to add the constraint now itself. Since we need to have fullscreen, we are giving height equal to the superview.
NSString *verticalString = [NSString stringWithFormat:#"V:|[%#(==parent)]|", [NSString stringWithFormat:#"v%d",i]];
// add the constraint
[contentScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalString options:0 metrics:nil views:viewsDict]];
// Since we need to horizontally arrange, we construct a string, with all the views in array looped and here also we have fullwidth of superview.
[horizontalString appendString:[NSString stringWithFormat:#"[%#(==parent)]", [NSString stringWithFormat:#"v%d",i]]];
}
// Close the string with the parent
[horizontalString appendString:#"|"];
// apply the constraint
[contentScrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:horizontalString options:0 metrics:nil views:viewsDict]];
}
Unfortunately the accepted answer by Rob didn't work for me. This is what worked:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NSArray *views = [[NSBundle mainBundle] loadNibNamed:#"myXib" owner:self options:nil];
[self addSubview:views[0]];
self.subviews[0].frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); //ADDED THIS FOR PROPER SIZE
}
return self;
}

Resources