I am trying to set the frame size of an UIImageView inside a subclass of UICollectionCell but it does not work. I use storyboard.
In the code, everything works but the last line regarding the imageView.
If i put the code in drawRect it works ok.
- (id)initWithCoder:(NSCoder *)decoder {
if ((self = [super initWithCoder:decoder]))
{
self.backgroundColor = [UIColor colorWithWhite:0.85f alpha:1.0f];
self.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.layer.borderWidth = 1.0f;
self.layer.cornerRadius = 8.0f;
self.layer.masksToBounds = NO;
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowRadius = 3.0f;
self.layer.shadowOffset = CGSizeMake(0.0f, 2.0f);
self.layer.shadowOpacity = 0.5f;
self.imageView.frame = CGRectMake(10, 10, 50, 50);
}
That is because your imageView (I believe it's and IBOutlet) is not yet initialized, it's still nil. Be aware that some of you variables/properties are being initialized inside init's method. Set you breakpoint and you will see. Try set the imageView values somewhere else such as drawRect (as you suggest) or awakeFromNib.
Is the image view being moved later by a different object? Try moving that code into layoutSubviews
Add this method:
- (void) layoutSubviews
{
[super layoutSubviews];
self.imageView.frame = CGRectMake(10, 10, 50, 50);
}
Related
I use CAGradientLayer in header view of TableView. To make scroll smooth I've turned shouldRasterize property to YES and it's caused the problem.
Gradient layer is drawn like it has a border. All frames I set in layoutSubviews and all its fields are integers.
Here are screenshots:
How it appears:
How it have to look like:
Here is a code related to this gradient layer
- (void)createShadow {
CAGradientLayer *shadowLayer= [CAGradientLayer layer];
UIColor *startColor = [UIColor colorWithWholeRed:236 green:235 blue:236];
UIColor *destinationColor = [UIColor colorWithWholeRed:248 green:248 blue:250];
shadowLayer.borderColor = [UIColor clearColor].CGColor;
shadowLayer.borderWidth = 0;
shadowLayer.colors = #[(id)startColor.CGColor,(id)destinationColor.CGColor];
shadowLayer.shouldRasterize = YES;
[self.layer addSublayer:shadowLayer];
self.shadowLayer = shadowLayer;
}
- (void)updateShadow {
CGRect newRect = CGRectMake(0, 0,
self.frame.size.width, ceil(self.frame.size.height * 0.3));
[self.shadowLayer setFrame:newRect];
}
- (void)layoutSubviews {
[super layoutSubviews];
[self updateShadow];
}
Tell me please if you know how to solve this problem)
I am having a big mental block figuring out something I think easy. Please see this very short video: http://screencast.com/t/eaW7rbECv4Ne.
I would like to draw a rectangle in my layoutSubviews method around the whole area that covers the subviews. I currently draw yellow rect around each term as you can see in the video.
I have a StatementView. In each key tap I am creating new objectView and adding it to my StatementView like below. I add the objectViews to a containerView and try to get the origin and size of the containerView in order to draw the stroke around it. However, it always gives me 0.
How should I update containerViews bounds values after I add the subviews to it?
// Created by ilteris on 1/31/15.
// Copyright (c) 2015 ilteris. All rights reserved.
#implementation QWZStatementView
-(id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.userInteractionEnabled = NO;
self.textField = [[MyUITextField alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
self.textField.inputView = [LNNumberpad defaultLNNumberpad];
self.textField.delegate = self;
self.isNumerator = NO;
self.isDenominator = NO;
[self addSubview:self.textField];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(statementOneTextFieldChanged:) name:UITextFieldTextDidChangeNotification object:nil];
self.containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
[self addSubview:self.containerView];
self.autoresizesSubviews = YES;
self.objectsArray = [NSMutableArray arrayWithCapacity:1];
self.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
}
return self;
}
-(void)statementOneTextFieldChanged:(NSNotification *)notification {
NSLog(#"statementOneTextFieldChanged");
QWZObjectView *objectView = [[QWZObjectView alloc] initWithFrame:self.bounds];
[self.containerView addSubview:objectView];
QWZTerm* term = [QWZQuestionDetailViewController createAndReturnCoreDataTermForJSONDict:objectData];
[objectView createTerm:term];
[self.objectsArray addObject:objectView];
[self setNeedsLayout];
}
- (void)layoutSubviews {
NSLog(#"layoutSubviews StatementView");
[super layoutSubviews];
CGSize totalSize = CGSizeMake(0, 0);
for (QWZObjectView* objectView in self.objectsArray) {
CGSize textSize = objectView.bounds.size;
objectView.frame = CGRectMake(totalSize.width , totalSize.height, textSize.width , textSize.height);
totalSize.width = textSize.width + totalSize.width;
}
CGRect bounds = self.containerView.bounds;
/*
NSLog(#"self.containerView.bounds is %#", NSStringFromCGRect(self.containerView.bounds)); //always 0.
bounds.origin = CGPointMake(totalSize.width/2, self.containerView.bounds.origin.y); //adding this code didn't help at all.
CGFloat borderWidth = 2.0f;
self.bounds = CGRectInset(self.bounds, -borderWidth, -borderWidth);
self.layer.borderColor = [UIColor redColor].CGColor;
self.layer.borderWidth = borderWidth;
*/
bounds.origin = CGPointMake(totalSize.width/2, self.containerView.bounds.origin.y);
self.containerView.bounds = bounds;
}
#end
I have a tableView with dynamic cell sizes, and having trouble resizing the shadow when the cells are being reused. This solution works on iOS8 but not on iOS7. Also the shadows show up correctly based on the cell size the first time the shadow is create, but they break after cells are being reused.
#implementation
static const CGFloat shadowWithInset = 2;
static const CGFloat shadowHeightOutset = 4;
- (void)awakeFromNib {
CALayer *layer = self.innerView.layer;
layer.shadowOffset = CGSizeMake(1, 1);
layer.shadowRadius = 3.0f;
layer.shadowColor = [[UIColor gray] CGColor];
layer.shadowOpacity = 0.8f;
//layer.shouldRasterize = YES;
//layer.rasterizationScale = [UIScreen mainScreen].scale;
CGSize size = layer.bounds.size;
layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(shadowWithInset, size.height-shadowHeightOutset, size.width-(shadowWithInset*2), shadowHeightOutset)].CGPath;
}
- (void)layoutSubViews {
[super layoutSubviews];
CGSize size = self.innerView.bounds.size;
layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(shadowWithInset, size.height-shadowHeightOutset, size.width-(shadowWithInset*2), shadowHeightOutset)].CGPath;
}
#end
After populating all textfields in cellForRowAtIndexPath I ended up doing this:
[self setNeedsLayout];
[self layoutIfNeeded];
I've created a custom button class to be used in my xibs that is basically just a button with a shadow with a label over it. However, the text in the label appears jagged (as though it is not being anti-aliased). Here's my code for the relevant part of the class (it's a very small class that inherits from UIButton).
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self internalInit];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self internalInit];
}
return self;
}
- (void)internalInit {
self.backgroundColor = [UIColor colorWithRed:22/255.0 green:72/255.0 blue:143/255.0 alpha:1.0];
CGRect frame = self.frame;
frame.origin = CGPointMake(floorf(frame.origin.x), floorf(frame.origin.y));
//self.frame = CGRectIntegral(frame);
frame = self.titleLabel.frame;
frame.origin = CGPointMake(floorf(frame.origin.x), floorf(frame.origin.y));
//self.titleLabel.frame = CGRectIntegral(frame);
// Shadow
self.layer.shadowOffset = CGSizeMake(0, 1.5);
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOpacity = 0.3;
self.layer.shouldRasterize = YES;
self.layer.shadowPath = [[UIBezierPath bezierPathWithRect:self.bounds] CGPath];
// Corner
self.layer.cornerRadius = 5;
}
I've tried troubleshooting the issue and I've found that this can occur when the origin for the label or the button is set at a non-integer value. However, I've checked the absolute value for both the button and the pixel and they are both set to integer values. I haven't been able to figure out what else could be going wrong and I cannot find any others who have had the same issue.
Generally when jaggies happen it's because the same view is being drawn multiple times over itself. Did you confirm this view is only being drawn once?
I'm implementing a custom UIView to display inside a UIScrollview. The thing is that I need the view to drop a shadow so I did:
#import <QuartzCore/QuartzCore.h>
#implementation CustomView
-(void)setupView{
self.layer.shadowColor = [UIColor blackColor].CGColor;
self.layer.shadowOpacity = 0.5;
self.layer.shadowRadius = 1;
self.layer.shadowOffset = CGSizeMake(.6f, .6f);
self.layer.cornerRadius = 2;
[...]
}
-(id)initWithFrame:(CGRect)frame{
if((self = [super initWithFrame:frame])){
[self setupView];
}
return self;
}
[...]
The point is that when I build and run this the scrollview is so slow and I just need to remove those lines where I was hacking the "self.layer" and The scrollview goes fast and smooth again.
whats the proper way to add shadows to my custom View?
This has to do with the all the redrawing that the UIView has to do when moving.
If you rasterize the layer it will become way smoother, this should do the trick:
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
self.layer.shouldRasterize = YES;
You could try to add a shadow path:
self.layer.shadowPath = [UIBezierPath bezierPathWithRect:self.bounds];
This might help a bit more.