Image 1 shows issue. label has flexible width & height constrains, also we adding fix width & height to expand with. in View hierarchy it shows fully expanded as expected, but issue in real view:
Image 2 shows fully expanded label in View hierarchy:
Lable code
self.textLabel = [[RAVerticallyAlignedLabel alloc] initWithFrame: self.bounds andVerticalTextAlignment: [self verticalTextAlignment]];
self.textLabel.backgroundColor = ClearColour;
self.textLabel.userInteractionEnabled = NO;
self.textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.textLabel.numberOfLines = 0;
viewToTruncate = self.textLabel;
textWidth = MAX(MIN(screenSize.width - 20, [label.text sizeWithAttributes: #{NSFontAttributeName : label.font}].width + 10);
[UIView animateWithDuration: 0.3 animations: ^
{
self->containerView.frame = CGRectMake(xPos, top , MIN(textWidth, screenSize.width - 2 * RAPadding), newTextviewHeight);
// Container view is added inside scroll view
self->containerView.layer.shadowRadius = kRATruncationUtiltityShadowRadius;
self->containerView.layer.shadowOpacity = kRATruncationUtiltityShadowOpacity;
self->containerView.layer.shadowOffset = kRATruncationUtiltityShadowOffset;
self->containerView.layer.shadowPath = [UIBezierPath bezierPathWithRect: self->containerView.bounds].CGPath;
self->containerView.layer.masksToBounds = NO;
self->viewToExpand.frame = CGRectMake(0, 0, textWidth + componentContentWidth, self->containerView.height);
//viewToExpand is UILable, added inside container view
self->viewToExpand.layer.borderWidth = 1.0;
self->viewToExpand.layer.borderColor = borderColor.CGColor;
self->viewToExpand.layer.backgroundColor = backgroundColor.CGColor;
}];
Found issue fix, it size wasn't issue but "gradientMask" was playing up on expand as below:
CAGradientLayer *gradientMask = [CAGradientLayer layer];
gradientMask.frame = CGRectMake(0, 0, viewToTruncate.width, viewToTruncate.height);
gradientMask.colors = #[(id)WhiteColour.CGColor,(id)WhiteColour.CGColor, (id)ClearColour.CGColor];
gradientMask.locations = #[#0, #(locationOfFade), #1];
viewToTruncate.layer.mask = gradientMask;
removing mask on expand , it was rendering as expected.
Related
I am trying to create a chart where a bar in the form of a UIView displays on top of a background UIView. I'd like both to display on top of the UIView for the whole screen. I have done this before successfully, but while I can get the first view to display, I somehow can't get my code to display the bar. Could it have something to do with setting the color? Or can anyone suggest why the second subview is not displaying.
My code:
//Make background box:
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat graphWidth = screenWidth-40;
CGFloat graphHeight = 160;
CGRect graphBounds =CGRectMake(20, 200, graphWidth, graphHeight);
float tableStartY = graphBounds.origin.y;
UIView *graphBox = [[UIView alloc] initWithFrame:graphBounds];
graphBox.backgroundColor = [UIColor colorWithRed:200.0/255.0 green:200.0/255.0 blue:200.0/255.0 alpha:0.2]; graphBox.layer.borderWidth = 1;
graphBox.layer.borderColor = [UIColor blueColor].CGColor;
//Make Bar
CGFloat barWidth = 20;
CGFloat barHeight = 100;
CGRect aBar = CGRectMake(20, tableStartY+1, barWidth, barHeight);
UIView *barView = [[UIView alloc] initWithFrame:aBar];
barView.backgroundColor = [UIColor blueColor];
barView.layer.borderWidth = 1;
barView.layer.borderColor = [UIColor redColor].CGColor;
// [graphBox addSubview:barView];
[self.view addSubview: graphBox];
If I run the above code, it displays the graphBox. If I add the bar directly to the view as a subView instead of the graphBox, the bar displays. However, if I uncomment out the line shown and add the barView first to the graphBox and then add the graphBox to the view, the barView does not display.
Thanks in advance for any suggestions.
If I understand correctly what you need to do, you should replace
CGRect aBar = CGRectMake(20, tableStartY+1, barWidth, barHeight);
with
CGRect aBar = CGRectMake(20, 1, barWidth, barHeight);
[edit: and obviously uncomment the addSubview line]
Perhaps this is an accident in your posted code, but you have specifically commented out where the barView would be added to the screen.
// [graphBox addSubview:barView];
In addition, as another answer lists, your offset is incorrect if you are adding barView to graphBox. If you add it to self.view instead, your offset is correct.
So, you've got two choices, depending on the containment you desire in your view hierarchy:
CGRect aBar = CGRectMake(20, 1, barWidth, barHeight);
// ...
[graphBox addSubview:barView];
or
CGRect aBar = CGRectMake(20, tableStartY+1, barWidth, barHeight);
// ...
[self.view addSubview: graphBox];
[self.view addSubview:barView];
Note that in the second option, the order is important to get the barView to display over top of the graphBox as they will be siblings.
I am trying to add a border to the selected segmented control. Currently, I have code which sets the border of 3px to the bottom of the whole segmented control:
CALayer *bottomBorder = [CALayer layer];
bottomBorder.borderColor = [UIColor redColor].CGColor;
bottomBorder.borderWidth = 3;
bottomBorder.frame = CGRectMake(0, self.segmentedControl.frame.size.height - bottomBorder.borderWidth, self.segmentedControl.frame.size.width, bottomBorder.borderWidth);
[self.segmentedControl.layer addSublayer:bottomBorder];
However, I want to add this border ONLY to the selected segmented control. How do I do this?
You can use the following code to dynamically add the selection:
// Removing previous selection
[bottomBorder removeFromSuperlayer];
// Creating new layer for selection
bottomBorder = [CALayer layer];
bottomBorder.borderColor = [UIColor redColor].CGColor;
bottomBorder.borderWidth = 3;
// Calculating frame
CGFloat width = self.segmentedControl.frame.size.width/3;
CGFloat x = self.segmentedControl.selectedSegmentIndex * width;
CGFloat y = self.segmentedControl.frame.size.height - bottomBorder.borderWidth;
bottomBorder.frame = CGRectMake(x, y,width, bottomBorder.borderWidth);
// Adding selection to segment
[self.segmentedControl.layer addSublayer:bottomBorder];
You need to remove the previous selection when new choice is selected, for that purpose make the bottomBorder layer as a member variable.
I converted the Objective-C solutions into swift3 it is working for me, My Segment controller width is equal to View width
#IBAction func SegmentAction(_ sender: UISegmentedControl) {
self.segmentBottomBorder?.removeFromSuperlayer()
self.segmentBottomBorder = CALayer()
self.segmentBottomBorder?.borderColor = UIColor.red.cgColor
self.segmentBottomBorder?.borderWidth = 3
let width: CGFloat = sender.frame.size.width/CGFloat(sender.numberOfSegments)
let x = CGFloat(sender.selectedSegmentIndex) * width
let y = sender.frame.size.height - (self.segmentBottomBorder?.borderWidth)!
self.segmentBottomBorder?.frame = CGRect(x: x, y: y, width: width, height: (self.segmentBottomBorder?.borderWidth)!)
sender.layer.addSublayer(self.segmentBottomBorder!)
}
This might not be the proper way, but you can give it a shot.
At the time you load the segment control, try this in viewdidload, so the layer gets added according to the selectedsegment button
if (self.segmentedControl.selectedSegmentIndex==0) {
CALayer *bottomBorder = [CALayer layer];
bottomBorder.borderColor = [UIColor redColor].CGColor;
bottomBorder.borderWidth = 3;
bottomBorder.frame = CGRectMake(0, self.segmentedControl.frame.size.height - bottomBorder.borderWidth, self.segmentedControl.frame.size.width/2, bottomBorder.borderWidth);
[self.segmentedControl.layer addSublayer:bottomBorder];
}else if (self.segmentedControl.selectedSegmentIndex==1){
//change the border layer frame
} else if (self.segmentedControl.selectedSegmentIndex==2){
//change the border layer frame
}
Again in the segmentcontrol action method, you can alter these changes
//Connect action to segmented control.
- (IBAction)segmentedControlAction:(id)sender {
if(segmentedControl.selectedSegmentIndex == 0)
{
NSLog(#"First Segment (Feed) Selected");
//Remove SuperLayer when segment is selected
[_bottomBorder removeFromSuperlayer];
// Creating new layer for selection
_bottomBorder = [CALayer layer];
_bottomBorder.borderColor = [UIColor redColor].CGColor;
_bottomBorder.borderWidth = 3;
// Calculating frame
CGFloat width = self.segmentedControl.frame.size.width/3;
CGFloat x = self.segmentedControl.selectedSegmentIndex * width;
CGFloat y = self.segmentedControl.frame.size.height - _bottomBorder.borderWidth;
_bottomBorder.frame = CGRectMake(x, y,width, _bottomBorder.borderWidth);
// Adding selection to segment
[self.segmentedControl.layer addSublayer:_bottomBorder];
}
else if(segmentedControl.selectedSegmentIndex == 1)
{
NSLog(#"Second Segment (Stations) Selected");
//Remove SuperLayer when segment is selected
[_bottomBorder removeFromSuperlayer];
// Creating new layer for selection
_bottomBorder = [CALayer layer];
_bottomBorder.borderColor = [UIColor redColor].CGColor;
_bottomBorder.borderWidth = 3;
// Calculating frame
CGFloat width = self.segmentedControl.frame.size.width/3;
CGFloat x = self.segmentedControl.frame.size.width/3;
CGFloat y = self.segmentedControl.frame.size.height - _bottomBorder.borderWidth;
_bottomBorder.frame = CGRectMake(x, y,width, _bottomBorder.borderWidth);
// Adding selection to segment
[self.segmentedControl.layer addSublayer:_bottomBorder];
}
else if(segmentedControl.selectedSegmentIndex == 2)
{
NSLog(#"Third Segment (Events) Selected");
//Remove SuperLayer when segment is selected
[_bottomBorder removeFromSuperlayer];
// Creating new layer for selection
_bottomBorder = [CALayer layer];
_bottomBorder.borderColor = [UIColor redColor].CGColor;
_bottomBorder.borderWidth = 3;
// Calculating frame
CGFloat width = self.segmentedControl.frame.size.width/3;
CGFloat x = self.view.bounds.size.width - self.segmentedControl.frame.size.width/3;
CGFloat y = self.segmentedControl.frame.size.height - _bottomBorder.borderWidth;
_bottomBorder.frame = CGRectMake(x, y,width, _bottomBorder.borderWidth);
// Adding selection to segment
[self.segmentedControl.layer addSublayer:_bottomBorder];
}
}
I have done following code but it does not work. It shows me in circle but in crop image format.
I want to fit image to circle.
UIImage * defaultImage = [UIImage imageNamed:#"empty.png"];
self.myImageView = [[UIImageView alloc] initWithImage:defaultImage];
CGRect myFrame = CGRectMake(90.0f, 100.0f, self.myImageView.frame.size.width/1.5,self.myImageView.frame.size.height/1.5);
[self.myImageView setFrame:myFrame];
[self.myImageView setContentMode:UIViewContentModeScaleAspectFit];
self.myImageView.layer.masksToBounds = NO;
self.myImageView.layer.cornerRadius = self.myImageView.frame.size.width/2;
self.myImageView.layer.borderColor = [UIColor blackColor].CGColor;
self.myImageView.clipsToBounds=YES;
self.myImageView.layer.borderWidth = 2.0f;
[self.view addSubview:self.myImageView];
You can use this method
-(void)setRoundedView:(UIImageView *)roundedView toDiameter:
(float)newSize;
{
CGPoint saveCenter = roundedView.center;
CGRect newFrame = CGRectMake(roundedView.frame.origin.x,
roundedView.frame.origin.y, newSize, newSize);
roundedView.frame = newFrame;
roundedView.layer.cornerRadius = newSize / 2.0;
roundedView.center = saveCenter;
}
Now call the method with your imageview
[self setRoundedView:self.myImageView toDiameter:self.myImageView.frame.size.width];
self.myImageView.clipsToBounds = YES;
Hope it helps
In short,
anyView.layer.cornerRadius = anyView.frame.size.width/2;
Make sure that clipsToBound property of that view is enabled.
Set width & height equal to Your imageView, then set cornerRadius of imageView to half of width & height.
[self createRoundUIView:self.userProfileImageView sizeDiameter:self.userProfileImageView.frame.size.width];
And add following code to bellow method,
-(void)createRoundUIView:(UIImageView *)inputView sizeDiameter:(float)diameterSize
{
CGPoint saveCenter = inputView.center;
CGRect frame = CGRectMake(inputView.frame.origin.x, inputView.frame.origin.y, diameterSize, diameterSize);
inputView.frame = frame;
inputView.layer.cornerRadius = diameterSize / 2.0;
inputView.center = saveCenter;
inputView.clipsToBounds = YES;
}
I found a useful library which works with cropping image in this link. I want to use it with only one cropRect which is ratio = 3.0f / 4.0f; instead of choosing them. I added below code in viewDidApper method of PECropViewController:
CGFloat ratio = 3.0f / 4.0f;
CGRect cropRect = self.cropView.cropRect;
CGFloat width = CGRectGetWidth(cropRect);
cropRect.size = CGSizeMake(width, width * ratio);
self.cropView.cropRect = cropRect;
But it is not working. There is (void)constrain:(id)sender method which works when I press Edit button. If I write above code in this method it works well. Here is the code:
(void)constrain:(id)sender
{
CGFloat ratio = 3.0f / 4.0f;
CGRect cropRect = self.cropView.cropRect;
CGFloat width = CGRectGetWidth(cropRect);
cropRect.size = CGSizeMake(width, width * ratio);
self.cropView.cropRect = cropRect;
return;
{
The problem is I can't change cropRect's ratio when croppingView appears.
if somebody is looking for solution for this question, i found it. I have just changed cropAspectRatio in PECropView:
- (void)setupImageView
{
CGRect cropRect = AVMakeRectWithAspectRatioInsideRect(self.image.size, self.insetRect);
self.scrollView.frame = cropRect;
self.scrollView.contentSize = cropRect.size;
self.zoomingView = [[UIView alloc] initWithFrame:self.scrollView.bounds];
self.zoomingView.backgroundColor = [UIColor clearColor];
[self.scrollView addSubview:self.zoomingView];
self.imageView = [[UIImageView alloc] initWithFrame:self.zoomingView.bounds];
self.imageView.backgroundColor = [UIColor clearColor];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.image = self.image;
[self.zoomingView addSubview:self.imageView];
//i added this line code
self.cropAspectRatio = 4 / 3.0;
}
Design:
View Hierarchy is as below:
UIScrollView (for paging multiple image)
UIScrollView (for enabling zoom on the UIImageView)
UIImageView
UIView (origin,size relative to UIImage in UIImageView)
UIView
UIView ...
UIScrollview
UIImageView
UIView
UIView ...
UIScrollView ... and so on
Implementation:
- (id)init
{
self = [super init];
if (self) {
// Custom initialization
self.minimumZoomScale = 1.0f;
self.maximumZoomScale = 4.0f;
self.zoomScale = 1.0f;
self.bouncesZoom = true;
self.bounces = true;
self.tag = 10;
self.alwaysBounceHorizontal = false;
self.autoresizesSubviews = YES;
self.zoomView = [[UIImageView alloc] init];
self.zoomView.userInteractionEnabled = YES;
self.zoomView.autoresizesSubviews = YES;
}
return self;
}
- (void)displayImage:(UIImage *)image
{
// Set the image in the view
[_zoomView setImage:image];
// Set the Frame size to the size of image size
// Ex. Resulting ScrollView frame = {0,0},{1250,1500}
// Ex. Resulting ImageView frame = {0,0}, {1250,1500}
CGRect scrollFrame = self.frame;
scrollFrame.size.width = image.size.width;
scrollFrame.size.height = image.size.height;
self.frame = scrollFrame;
CGRect iViewFrame = _zoomView.frame;
iViewFrame.size.width = image.size.width;
iViewFrame.size.height = image.size.height;
_zoomView.frame = iViewFrame;
// Add subviews before resetting the contentsize
for (customClass* field in list.fields) {
UIView* view = [[UIView alloc] initWithFrame:CGRectMake([field.x floatValue], [field.y floatValue], [field.width floatValue], [field.height floatValue])];
view.backgroundColor = [UIColor redColor];
view.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin |UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[_zoomView addSubview:view];
}
// Set the Frame size to the size of scrollview frame size
// Ex. Resulting ScrollView Frame = {0,0},{320,460}
// Ex. Resulting ImageView Frame = {0,0},{320,460}
CGRect scrollViewFrame = self.frame;
scrollViewFrame.size.width = 320.0f;
scrollViewFrame.size.height = 460.0f;
self.frame = scrollViewFrame;
CGRect imageViewFrame = _zoomView.frame;
imageViewFrame.size.width = self.bounds.size.width;
imageViewFrame.size.height = self.bounds.size.height;
_zoomView.frame = imageViewFrame;
self.contentSize = _zoomView.bounds.size;
[self addSubview:_zoomView];
}
Above is the code that I tried implementing. It adds the UIViews to the UIImageView inside the UIScrollView. But the relative origin of the UIView is not correct (both before and after resizing).
Is there anything I should be doing differently to get the UIViews correctly placed inside the UIImageView?
This was top hit on Google for "scrollview subviews wont resize". For anyone else following that link:
Looking at your source, and comparing to mine, I realised that in Interface Builder, my NIB file had the tickbox for "auto size subviews" unticked. I have a vague memory this might be because in an old version of Xcode (this is an old project that's been maintained for a while) ... UIScrollView defaulted to having it switched off.
So: check that you've got it set correctly in Xcode / Interface Builder, and/or that you're setting it in code.