- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self setBackgroundColor:[UIColor clearColor]];
//[self createViews];
}
return self;
}
- (void)drawRect:(CGRect)rect
{
NSLog(#"draw rect");
[self createViews];
}
I'm creating a custom UITableViewCell. I require creating a UILabel that depends on the height of the UITableViewCell, and the height is not yet set in initWithStyle (it returns the default 44 when in reality the height of my cell varies greatly). For this reason, I call my createViews function in drawRect. This was working well, however I'm noticing that the function can be called again when I insert and delete rows.
My Question:
Does it make sense to call my createViews function inside drawRect?
You have few options here.
1. Use layoutSubviews/awakeFromNib, check whether the subviews were created, if no, create them with correct frames.
2. Use init to create views with:
Constraints
Without constraints and in layoutSubviews/awakeFromNib try to change the frame
Related
I subclassed UITableViewCell (subtitle style) and I have to set the imageView property runtime. The size of the image can be different for each cell, but I want the imageView to be squared (fixed size). For this reason I set at first a squared image as a placeholder. This is the code of the init method:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
// Other settings...
[self.imageView.layer setCornerRadius:2.0f];
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
[self.imageView setClipsToBounds:YES];
self.imageView.image = [UIImage imageNamed:#"placeholder"];
return self;
}
In the layoutSubviews method I just call the super method, while I set the image in the UITableViewController once I get it from its URL. This is working fine as you can see here:
But when I enter in edit mode something happens and I get this:
I tried to set imageView frame in layoutSubviews method but the image is not aligned and textDetail label keep starting in the same position of the above screenshot... where am I wrong?
I've created a custom UITableViewCell class where I've created a label and imageview, and connected them via storyboard. What's the best place to apply corner radius, border width, etc. to the imageView?
I tried the following in the custom class' init method but it didn't quite work:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
productImageView.layer.borderColor = (__bridge CGColorRef)([UIColor whiteColor]);
productImageView.layer.borderWidth = 3.0f;
productImageView.layer.cornerRadius = 36.0f;
}
return self;
}
What's wrong here?
Are you doing in this in the UITableViewCell subclass? If so you need add this in awakeFromNib or prepareForReuse. When init is called the image view doesn't exist yet. Also do self.productImageView.clipsToBounds = YES;
I want to add two adjacent custom buttons in the UITableView's accessory view.
I tried doing cell.accessoryView = customButton; and then
cell.accessoryView = customButton2 .It is obvious that this replaces the previous button.
Thanks for any help!
You can add a UIView containing the two buttons as a custom accessoryView.
UIView *buttonsView = [...];
// add buttons to buttonsView
cell.accessoryView = buttonsView;
Or you can subclass UITableViewCell and add two buttons there.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
UIButton *buttonA = ....
UIButton *buttonB = ....
[self.contentView addSubview:buttonA];
[self.contentView addSubview:buttonB];
}
return self;
}
If you haven't done a custom UITableViewCell before this article might help.
http://code.tutsplus.com/tutorials/ios-sdk-crafting-custom-uitableview-cells--mobile-15702
You can make a custom UIView class with your buttons placed inside of it (as subviews: [self addSubview:button]). Then you can assign your custom UIView object as accessoryView of a cell.
cell.accessoryView = yourCustomView;
I have a subclassed UITableViewCell, if I add a UIScrollView to cell's contentView, can't perform the segue, if I comment the line, it can perform the segue.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self setup];
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self setup];
}
- (void)setup
{
UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
scrolView.contentSize = CGSizeMake(CGRectGetWidth(self.bounds)+kButtonWidth, CGRectGetHeight(self.bounds));
scrolView.delegate = self;
scrolView.showsHorizontalScrollIndicator = NO;
// [self.contentView addSubview:scrolView];
}
You are adding a scroll view that is the full size of the cell in the content view, on top of all other views in the cell. It's covering them up, so no clicks get through. I suspect you want to add a scroll view as a container for your other views. I don't know how you could do that with all the standard views that the table view base class manages for you. You'd have to somehow override the behavior of the base class and change the content view into a scroll-view.
Alternatively you could do what you are doing, but then you would need to replace all the standard table view cell fields and behaviors with your own, which would be nearly impossible.
Adding a scroll view to a table view cell is probably a bad idea. The table view itself is a subclass of a scroll view, and it will be very hard/impossible to sort out which gestures are supposed to scroll the table view and which are supposed to scroll a cell. The only way I could see that working is if the cell's scroll view is limited to horizontal scrolling.
I am re-using a UIView subclass in a few places, but need the layout to be slightly different on occasion - sometimes the subviews are laid out horizontally and sometimes vertically.
I would like to somehow replicate the 'initWithStyle' approach that UITableView and other UIViews employ. It should be possible to 'initWithStyle' but there should be a default also. It should also be possible to change the style using setStyle.
What are the steps to achieve this? I tried defining an enum and a new initializer, but I am out of my depth here.
Sounds like you're on the right track, so I'm not sure how helpful I can be. Create your public initializers and public setStyle methods. Sorry for any typos. I'm doing this without an editor.
.h
-(id)initWithFrame:(CGRect)frame;
-(id)initWithFrame:(CGRect)frame style:(MyStyleEnum)myStyleEnum;
-(void)setStyle:(MyStyleEnum)myStyleEnum;
.m
//here's your default method which passes your default style to your custom init method
-(id)initWithFrame:(CGRect)frame {
return [self initWithFrame:frame style:myStyleEnumDefault];
}
//your custom init method that takes a style
-(id)initWithFrame:(CGRect)frame style:(MyStyleEnum)myStyleEnum {
self = [super initWithFrame:frame];
if(self) {
[self setStyle:myStyleEnum];
}
return self;
}
//this can be called after initialization
-(void)setStyle:(MyStyleEnum)myStyleEnum {
//make sure the view is clear before you layout the subviews
//[self.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];//not needed adjusting constraints and not repopulating the view
//change the view constraints to match the style passed in
//the acutally changing, should probably be done in separate methods (personal preference)
if(myStyleEnum == myStyleEnumDefault) {
//change constraints to be the default constraints
} else if(myStyleEnum == myStyleEnumA) {
//change constraints to be the A constraints
} else if(myStyleEnum == myStyleEnumB) {
//change constraints to be the B constraints
}
}