I'm trying to create a custom view cell. But it's not showing. The tableview cells are created correct number but their contents are not showed.
VDCoreTableViewCell.h
#interface VDCoreTableViewCell : UITableViewCell
#property (weak, nonatomic) UIImageView *cell_image;
#property (strong, nonatomic) UILabel *title;
#property (weak, nonatomic) UILabel *subTitle;
VDCoreTableViewCell.m
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.title = [[UILabel alloc] initWithFrame:self.bounds];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.title.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor]CGColor], (id)[[UIColor blackColor]CGColor], nil];
[self.title.layer insertSublayer:gradientLayer atIndex:0];
}
return self;
}
VDViewController.h
#interface VDViewController : VDCoreViewController <UITableViewDelegate, UITableViewDataSource>
#property (strong, nonatomic) UITableView *tableView;
#end
VDViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
[self.tableView setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin|UIViewAutoresizingFlexibleWidth];
[self.tableView setDataSource:self];
[self.tableView setDelegate:self];
[self.tableView registerClass: [VDCoreTableViewCell class] forCellReuseIdentifier:#"cell_id"];
[self.view addSubview:self.tableView];
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
VDCoreTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[VDCoreTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
cell.title.text = #"test";
cell.subTitle.text = #"test";
}
Help please.
You have to add the titleLabel to your cell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.title = [[UILabel alloc] initWithFrame:self.bounds];
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.frame = self.title.bounds;
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor]CGColor], (id)[[UIColor blackColor]CGColor], nil];
[self.title.layer insertSublayer:gradientLayer atIndex:0];
[self.contentView addSubview:self.title]; //Add your label what you have created to content view
}
return self;
}
Related
I'm working with iOS8 Self-Sizing cell and I want the cell resize to fit its subview, messageBodyButton and profileImageView.
profileImageView's size is fixed. As you can see in the picture below, the messageBodyButton doesn't resize to fit its titleLabel.
Why did this happen? How to fix this bug using Auto Layout?
And when the titleLabel's content changed(say, the model's data changed), how should I update constraints so that the cell height can be calculated correctly?
Here is my code:
RXTChatCell.m:
#property (nonatomic, strong) UILabel *timeLabel;
#property (nonatomic, strong) UIImageView *profileImageView;
#property (nonatomic, strong) UIButton *messageBodyButton;
#property (nonatomic, assign) BOOL needUpdateConstraints;
#property (nonatomic, assign) BOOL didSetUpConstraints;
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
_timeLabel = [[UILabel alloc] init];
_timeLabel.text = #"19:00";
[self.contentView addSubview:_timeLabel];
_profileImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"placeholder"]];
[self.contentView addSubview:_profileImageView];
_messageBodyButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_messageBodyButton.titleLabel setLineBreakMode:NSLineBreakByTruncatingTail];
[_messageBodyButton.titleLabel setTextAlignment:NSTextAlignmentRight];
_messageBodyButton.titleLabel.numberOfLines = 0;
_messageBodyButton.titleLabel.backgroundColor = UIColor.grayColor;
[self.contentView addSubview:_messageBodyButton];
_timeLabel.backgroundColor = UIColor.redColor;
_profileImageView.backgroundColor = UIColor.greenColor;
_messageBodyButton.backgroundColor = UIColor.blueColor;
self.contentView.backgroundColor = UIColor.orangeColor;
}
return self;
}
- (void)updateConstraints
{
if (!self.didSetUpConstraints) { // set up constraints
[_timeLabel makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contentView.topMargin);
make.centerX.equalTo(self.contentView);
}];
[_profileImageView makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_timeLabel.bottom).offset(10);
make.right.equalTo(self.contentView).offset(-10);
make.width.and.height.equalTo(50);
make.bottom.lessThanOrEqualTo(self.contentView.bottomMargin);
}];
[_messageBodyButton makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_profileImageView);
make.right.equalTo(_profileImageView.left).offset(-10);
make.left.equalTo(self.contentView).offset(10);
make.bottom.lessThanOrEqualTo(self.contentView.bottomMargin);
}];
self.didSetUpConstraints = YES;
}
if (self.needUpdateConstraints){
// here, how should I update constraints?
}
[super updateConstraints];
}
- (void)setMessage:(RXTChatMessage *)message
{
EMTextMessageBody *body = (EMTextMessageBody *)message.messageBody.body;
[self.messageBodyButton setTitle:body.text forState:UIControlStateNormal];
self.needUpdateConstraints = YES;
[self setNeedsUpdateConstraints];
}
RXTChatViewController.m:
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.estimatedRowHeight = 44;
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
RXTChatMessage *message = self.messages[indexPath.row];
RXTChatCell *cell = [tableView dequeueReusableCellWithIdentifier:RXTChatCellId];
if (cell == nil) {
cell = [[self alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:RXTChatCellId];
}
cell.message = message;
return cell;
}
Select Your Button -> Go to Editor -> Size to fit content.
Remove fixed height constraint for your button (only set leading,trailing,top bottom) constraint (Superview should be your cell view).
This should solve your problem
let me know if it solves your issue.
If I use this code to indent from left, everything is indented (separator + content)
table.contentInset = UIEdgeInsetsMake(0, 20, 0, 0);
Same if I use this:
cell.layoutMargins = UIEdgeInsetsMake(0, 20, 0, 0);
This doesn't help neither, because it doesn't move the image.
cell.indentationLevel = 10;
You can use a CustomTableCell to get what you want:
At first, in ViewController:
#import "ViewController.h"
#import "MyTableCell.h"
#interface ViewController ()
#property UITableView *tableView;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
_tableView.separatorStyle = UITableViewCellSelectionStyleNone;
_tableView.backgroundColor = [UIColor grayColor];
_tableView.dataSource = self;
_tableView.delegate = self;
[self.view addSubview:_tableView];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 20;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MyTableCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (nil == cell) {
cell = [[MyTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"];
}
//Update data for cell
return cell;
}
#end
This is MyTableCell.h:
#import "MyTableCell.h"
#interface MyTableCell()
#property UIView *containerView;
#property UIView *separationLine;
#end
#implementation MyTableCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
_containerView = [[UIView alloc] init];
_containerView.backgroundColor = [UIColor redColor];
[self addSubview:_containerView];
_separationLine = [[UIView alloc] init];
_separationLine.backgroundColor = [UIColor blackColor];
[self addSubview:_separationLine];
return self;
}
-(void)layoutSubviews{
_containerView.frame = CGRectMake(20, 0, self.frame.size.width-20, self.frame.size.height-1);
_separationLine.frame = CGRectMake(10, self.frame.size.height-1, self.frame.size.width-10, 1);
}
#end
And this is the screenshot for the code:
You can modify the code in "layoutSubviews" as your wish.
Hope it can help you.
I'm having a problem with one of my delegate methods. I have a collectionViewController to which I have added a UILongPressGestureRecognizer, which is calling a delegate method fadeOutLabels in my UICollectionViewCell. I can confirm the delegate method being called by a NSLog statement NSLog(#"fadeOutLabels was called");. But the other code inside that function isn't being executed. I'm quite sure I'm missing something completely obvious, but I can't seem to figure it out myself. Code as follows:
FOFPhotoCell.h
#protocol FOFPhotoCellDelegate <NSObject>
#required
-(void)fadeOutLabels;
#end
#interface FOFPhotoCell : UICollectionViewCell {
id delegate;
}
#property (nonatomic, weak) id<FOFPhotoCellDelegate> delegate;
#property (nonatomic) UIImageView *imageView;
#property (nonatomic) NSDictionary *photo;
#property (nonatomic) NSArray *fetchPhotos;
#property (nonatomic) UILabel *titleLabel;
#end
FOFPhotoCell.m
#implementation FOFPhotoCell
#synthesize delegate = _delegate;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
CGFloat widthFromBounds = self.contentView.bounds.size.width;
self.imageView = [[UIImageView alloc] init];
[self.contentView insertSubview:self.imageView atIndex:0];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 30, widthFromBounds, 60)];
self.titleLabel = titleLabel;
self.titleLabel.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.3];
self.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
self.titleLabel.textColor = [UIColor whiteColor];
self.titleLabel.textAlignment = NSTextAlignmentCenter;
[self.contentView insertSubview:self.titleLabel atIndex:1];
}
return self;
}
-(void)fadeOutLabels
{
NSLog(#"fadeOutLabels was called");
[UIView animateWithDuration:1.0
delay:0.0 /* do not add a delay because we will use performSelector. */
options:UIViewAnimationOptionCurveEaseIn
animations:^ {
self.titleLabel.alpha = 0.0;
}
completion:^(BOOL finished) {
[self.titleLabel removeFromSuperview];
}];
}
FOFPhotosViewController.h
#import <UIKit/UIKit.h>
#import "FOFPhotoCell.h"
#interface FOFPhotosViewController : UICollectionViewController <FOFPhotoCellDelegate>
#end
FOFPhotosViewController.m
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
FOFPhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"photo" forIndexPath:indexPath];
NSArray *photosArray = [self.dishes valueForKeyPath:#"avatar_url"];
NSArray *nameArray = [self.dishes valueForKeyPath:#"name"];
// NSLog(#"photoURL %#", _responseDictionary);
cell.backgroundColor = [UIColor lightGrayColor];
[cell.imageView setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://xx.yy.zz.qq:4000%#",[photosArray objectAtIndex: indexPath.row]]]];
cell.titleLabel.text = [NSString stringWithFormat:#"%#", [nameArray objectAtIndex:indexPath.row]];
UILongPressGestureRecognizer *tapAndHold = [[UILongPressGestureRecognizer alloc] initWithTarget:cell action:#selector(fadeOutLabels)];
tapAndHold.minimumPressDuration = 0.5;
[self.collectionView addGestureRecognizer:tapAndHold];
[self.collectionView reloadItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
return cell;
}
I would really appreciate if some one could help me with this issue.
Thanks in advance
Chris
I believe your problem comes from the LongPressGestureRecognizer that should be instantiated in your custom cell and not in your view controller.
Basically, if you have a hundred cell how the long press gesture recognizer is supposed to know which cell you have pressed and which label to fade out.
You can try this instead, in your custom cell :
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UILongPressGestureRecognizer *tapAndHold = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(fadeOutLabels)];
tapAndHold.minimumPressDuration = 0.5;
[self addGestureRecognizer:tapAndHold];
....
}
}
And of course remove those lines in the view controller.
CustomCell.h
#interface CustomCell : UITableViewCell
//Properties created in Code, not via IB.
#property (nonatomic, strong) UILabel *labelUsername;
#property (nonatomic, strong) UIView *circle;
//Properties Created through IB by control+drag
#property (nonatomic, strong) UILabel *labelFirstName;
#property (nonatomic, strong) UILabel *labelLastName;
#end
CustomCell.m
#implementation CustomCell
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//Creating properties in code
self.circle = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 40.0f, 40.0f)];
[self.circle setBackgroundColor:[UIColor brownColor];
self.labelUsername = [[UILabel alloc] initWithFrame:CGRectMake(15, 20, 200.0f, 50.0f)];
self.labelUsername.textColor = [UIColor blackColor];
[self.contentView addSubview:self.labelUsername];
[self.contentView addSubview:self.circle];
}
return self;
}
tableView.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *customCellIdentifier = #"CustomCell";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:customCellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:inviteCellIdentifier];
}
cell.labelFirstName.text = #"FirstName";
cell.labelLastName.text = #"LastName";
return cell;
}
The code above continued to show labelUsername and circle. However, the properties created using the IB (labelFirstName and labelLastName) did not appear.
So in tableView.m in viewDidLoad I registered the Nib with the following code:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:#"CustomCell"
bundle:[NSBundle mainBundle]]
forCellReuseIdentifier:#"CustomCell"];
}
Now labelFirstName and labelLastName appear, but the properties created with code (labelUsername and circle) DO NOT appear.
How can I get all 4 properties to show?
Try this in CustomCell.m,
- (void)awakeFromNib
{
[super awakeFromNib];
self.circle = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 40.0f, 40.0f)];
[self.circle setBackgroundColor:[UIColor brownColor];
self.labelUsername = [[UILabel alloc] initWithFrame:CGRectMake(15, 20, 200.0f, 50.0f)];
self.labelUsername.textColor = [UIColor blackColor];
[self.contentView addSubview:self.labelUsername];
[self.contentView addSubview:self.circle];
}
Try this after self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
NSArray *views = [[NSBundle mainBundle]loadNibNamed:#"yourNibName" owner:self options:NULL];
[self addSubview:[views lastObject]];
I am using this code for multiple cell types in a UITableView
The problem is that the cell text is invisible. The code for cellForRowAtIndexPath as well as the cell class code is given below:
code:
static NSString *kCellIdentifier = #"NewsViewControllerTableCell";
static NSString *kCellIdentifier2 = #"SubscribeCell";
if ((indexPath.row==0) && ([[NSUserDefaults standardUserDefaults] boolForKey:#"subscribeButtonOption"]))
{
SubscribeCell* cell = (SubscribeCell*)[tableView dequeueReusableCellWithIdentifier:kCellIdentifier2];
if (cell == nil) {
cell = [[[SubscribeCell alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 35.0) reuseIdentifier:kCellIdentifier2] autorelease];
cell.contentView.backgroundColor = kColorR53G53B53;
cell.subscribeLabel.font = kLucidaSansStdFontBold_14;
cell.subscribeLabel.textColor = [UIColor whiteColor];
}
cell.subscribeLabel.textColor=[UIColor redColor];
cell.subscribeLabel.text = #"+ SUBSCRIBE TO NEWSLETTER";
cell.selectedBackgroundView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
cell.selectedBackgroundView.backgroundColor =kColorR53G53B53;
[cell setNeedsDisplay];
return cell;
}
else
{
//another cell
}
=========
header:
#import <UIKit/UIKit.h>
#interface SubscribeCell : UITableViewCell{
UILabel *subscribeLabel;
}
#property(nonatomic, retain) UILabel *subscribeLabel;
#end
and implementation class:
#import "SubscribeCell.h"
#implementation SubscribeCell
#synthesize subscribeLabel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
subscribeLabel=[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 323.0, 40.0)];
subscribeLabel.textColor=[UIColor whiteColor];
self.backgroundColor=kColorR53G53B53;
}
return self;
}
Check to see if subscribeLabel is nil. You're creating it in initWithNibName:bundle: but are initializing with initWithFrame:reuseIdentifier:, so it's not reaching your label creation code.
If I try to compile your code, I get an error message stating that UITableViewCell does not declare a method called 'initWithNibName: bundle:'. You should use the proper initialization method 'initWithStyle: reuseIdentifier:'. You also forget to add the subscribeLabel to the contentView of the cell.
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
subscribeLabel=[[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, 323.0, 40.0)];
subscribeLabel.textColor=[UIColor whiteColor];
[self.contentView addSubview:subscribeLabel];
self.backgroundColor=kColorR53G53B53;
}
return self;
}