label display text not well when use [cell setNeedsDisplay] - ios

I have a UICollectionView to display username of user, and when I add new or modify a user -> I will update into database -> then get all data again(from the data base). and then reload UICollectionView. All I want is: if I modify a user at index 3 then after reload this user is still stay at index 3(and if I add a new user this user will display at the end position). So that I use setNeedsDisplay. But I have a problem that my label display text not well when I use setNeedsDisplay,as below:
when I comment out [cell setNeedsDisplay]; then the text of label is display well. But the index of each user is not display right as I want.Here is my code
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
if(!dbManager)
dbManager = [DBManager sharedInstant];
UIBarButtonItem *btnAdd = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(showAdd)];
self.navigationItem.rightBarButtonItem = btnAdd;
UIBarButtonItem *btnFilter = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(showFilter)];
self.navigationItem.leftBarButtonItem = btnFilter;
[[DBManager sharedInstant] setDelegate:self];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView setBackgroundColor:[UIColor clearColor]];
[self.collectionView registerClass:[UserCollectionItemView class] forCellWithReuseIdentifier:#"UserCollectionItemView"];
cells = [[NSMutableArray alloc] init];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (!dbManager.synchronized) {
[datasource removeAllObjects];
datasource = nil;
if (contactType == ContactTypeCustomer)
[dbManager requestData:kDbCustomers predicate:nil target:self];
else if (contactType == ContactTypeSuppplier)
[dbManager requestData:kDbSuppliers predicate:nil target:self];
}
[self setLayout];
}
and for collectionview:
#pragma mark
#pragma UICollectionDelegate
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)cv numberOfItemsInSection:(NSInteger)section
{
return [datasource count];
}
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
{
[cells addObject:cell];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UserCollectionItemView *cell;
// if([cells count])
// {
// cell = [cells lastObject];
// [cells removeLastObject];
// }
// else
cell = [cv dequeueReusableCellWithReuseIdentifier:#"UserCollectionItemView" forIndexPath:indexPath];
if (contactType == ContactTypeCustomer) {
POSCustomer *customer = [datasource objectAtIndex:indexPath.item];
cell.displayname = customer.CompanyName;
}
else if (contactType == ContactTypeSuppplier){
POSSupplier *supplier = [datasource objectAtIndex:indexPath.item];
cell.displayname = supplier.CompanyName;
}
cell.backgroundColor = [UIColor clearColor];
[cell setNeedsDisplay];
return cell;
}
- (void)collectionView:(UICollectionView *)cv didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
dbManager.synchronized = YES;
if (contactType == ContactTypeCustomer) {
POSCustomer *customers = [datasource objectAtIndex:indexPath.item];
[self showEditCustomer:customers];
}
else if (contactType == ContactTypeSuppplier){
POSSupplier *suppliers = [datasource objectAtIndex:indexPath.item];
[self showEditSupplier:suppliers];
}
}
-(void)showEditCustomer:(POSCustomer *)customer{
ContactFormViewController *form = [[ContactFormViewController alloc] initWithNibName:#"ContactFormViewController" bundle:nil];
[form setContactType:ContactTypeCustomer];
form.posCustomer = customer;
[self.navigationController pushViewController:form animated:YES];
}
-(void)showEditSupplier:(POSSupplier *)supplier{
ContactFormViewController *form = [[ContactFormViewController alloc] initWithNibName:#"ContactFormViewController" bundle:nil];
[form setContactType:ContactTypeSuppplier];
form.posSupplier = supplier;
[self.navigationController pushViewController:form animated:YES];
}
#pragma mark
#pragma DBDelegate
- (void)requestDataCompleted:(NSMutableArray *)results
{
datasource = results;
[self.collectionView reloadData];
}
and here is for custom collectionview:
#synthesize displayname;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
- (void)drawRect:(CGRect)rect
{
CGRect frame = self.contentView.frame;
UIView *view = [[UIView alloc] initWithFrame:frame];
view.layer.borderWidth = 0.5;
[view.layer setBorderColor:[UIColor colorWithRed:0.3 green:0.6 blue:0.2 alpha:1].CGColor];
view.layer.cornerRadius = 5;
[view setBackgroundColor:[UIColor colorWithRed:0.3 green:0.6 blue:0.2 alpha:0.3]];
UIImageView *avatarView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 10, frame.size.width, rect.size.width)];
[avatarView setBackgroundColor:[UIColor clearColor]];
[avatarView setImage:[UIImage imageNamed:#"users_icon"]];
[view addSubview:avatarView];
UILabel *displayName = [[UILabel alloc] initWithFrame:CGRectMake(3, frame.size.width - 10, rect.size.width - 6, 50)];
displayName.numberOfLines = 2;
displayName.text = displayname;
[displayName setFont:[UIFont fontWithName:#"Arial" size:12]];
displayName.textAlignment = NSTextAlignmentCenter;
[displayName setTextColor:[UIColor colorWithRed:0.3 green:0.6 blue:0.2 alpha:1]];
[view addSubview:displayName];
[self.contentView addSubview:view];
}
Thanks for any helps.

Because of this line [self.contentView addSubview:view];, It've added multiple times because setNeedDisplay will call drawRect: every time. To avoid this, try below..
UIView *view = [[UIView alloc] initWithFrame:frame];
view.tag = SomeTagValue;
.
.
.
.
UIView *preView = [self.contentView viewWithTag:SomeTagValue];
[preView removeFromSuperview];
[self.contentView addSubview:view];

Related

UITableView dislocates automatically

Issue
I am encountering a weird issue with UITableView. Following is the link to video that explains the issue I'm facing. (turned on slow animation)
https://dl.dropboxusercontent.com/u/97646145/Issue/UITableView_Issue.swf
The table is dislocating only when the controller is visited for the first time. Later on, the issue isn't popping.
Code
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBarHidden = FALSE;
[self.navigationController.topViewController.navigationItem setHidesBackButton:YES];
[self.view setBackgroundColor:[UIColor clearColor]];
_extrasTable = [[UITableView alloc] initWithFrame:CGRectMake(50, 44, CGRectGetWidth(self.view.frame) - 75, CGRectGetHeight(self.view.frame) - 44) style:UITableViewStylePlain];
}
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[_extrasTable setBackgroundColor:[UIColor clearColor]];
_extrasTable.rowHeight = CGRectGetHeight(_extrasTable.bounds) / 5;
_extrasTable.separatorStyle = UITableViewCellSeparatorStyleNone;
_extrasTable.dataSource = self;
_extrasTable.delegate = self;
[self.view addSubview:_extrasTable];];
}
#pragma mark - UITableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [EXTRAS count];
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
cell.textLabel.font = [UIFont fontWithName:NobileMedium size:15];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.text = EXTRAS[indexPath.row];
[cell setBackgroundColor:[UIColor clearColor]];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}
#pragma mark - Visible cells
- (NSArray*)visibleCells
{
return [_extrasTable visibleCells];
}
EDIT
I'm adding this TableView' controller as a subview to another View controller. The code for the same as follows:
for (UIView *view in [self.view subviews]) {
[view removeFromSuperview];
}
[self.navigationController setNavigationBarHidden:NO];
[self.navigationController.topViewController.navigationItem setHidesBackButton:YES];
[currentController removeFromParentViewController];//currentController - instance of UIViewController
MMExtrasVC *controller = [[MMExtrasVC alloc] init];//the controller that contains table view
controller.view.frame = [[self view] bounds];
[self.view addSubview:controller.view];
[self addChildViewController:controller];
[controller didMoveToParentViewController:self];
currentController = controller;
Implement ViewDidLayoutSubView and set Frame there for your table.
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
_extrasTable setFrame:CGRectMake(x, y, width, height)];
}
I think the problem is caused by the navigation bar.
Firstly, I would try removing below from viewDidLoad:
self.navigationController.navigationBarHidden = FALSE;
Secondly, I would remove the tick (if there's one) from:
Extend Edges, Under Top Bars
from the Attributes Inspector of the view controller.

Incorrect UITableViewCell gets highlighed when dequeued

I have written a subclass of UITableViewCell to allow horizontal swipe to give some actions to users. Here is what I am doing:
Create a scrollView
Create a buttonView and add in scrollView.
Create a UIButton and add all cell controls as subview to it. Add in scroll view.
Add scrollView to cell contentView.
For #3 I am setting the highlighted image to give a feel of user tap like in normal cell.
The issue is when my table view is loaded on iOS 6 with 6 cells and user tap on any of the cell, cell gets highlighted properly and the details are shown properly for the tapped cell. But if user scrolls up and first cell is re-used and user tap on the top cell (which is second row), cell next to it gets highlighted. If user scrolls up and purge 2 cells and tap on the top cell, cell 2 cells down it gets highlighted. Although tapped cell shows the data of the correct cell.
Any clue?
- (id)initWithStyle:(UITableViewCellStyle)iStyle reuseIdentifier:(NSString *)iReuseIdentifier andMenuButtonDetails:(NSArray *)iMenuButtonDetails {
if ((self = [super initWithStyle:iStyle reuseIdentifier:iReuseIdentifier])) {
self.catchWidth = kMenuButtonWidth * [iMenuButtonDetails count];
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(kScreenOrigin, kScreenOrigin, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
self.scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.bounds) + self.catchWidth, CGRectGetHeight(self.bounds));
self.scrollView.delegate = self;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.scrollEnabled = YES;
[self.contentView addSubview:self.scrollView];
self.scrollViewButtonView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.bounds) - self.catchWidth, kScreenOrigin, self.catchWidth, CGRectGetHeight(self.bounds))];
[self.scrollView addSubview:self.scrollViewButtonView];
if ([iMenuButtonDetails count]) {
// Adding menu buttons to the cell.
CGFloat anXOffset = kScreenOrigin;
for (NSDictionary *aMenuButton in iMenuButtonDetails) {
if ([aMenuButton containsObjectForKey:kTitleKey]) {
UIButton *aButton = [[UIButton alloc] initWithFrame:CGRectMake(anXOffset, kScreenOrigin, kMenuButtonWidth, kCellHeight64)];
[aButton addTarget:self action:#selector(buttonSelected:) forControlEvents:UIControlEventTouchUpInside];
if ([aMenuButton containsObjectForKey:kButtonTagKey])
aButton.tag = [[aMenuButton stringForKey:kButtonTagKey] intValue];
aButton.titleEdgeInsets = UIEdgeInsetsMake(kScreenOrigin, 2.0, kScreenOrigin, 2.0);
aButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
[aButton.titleLabel setTextAlignment:NSTextAlignmentCenter];
[aButton setTitle:[aMenuButton stringForKey:kTitleKey] forState:UIControlStateNormal];
[aButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
if ([aMenuButton objectForKey:kButtonColorKey]) {
aButton.backgroundColor = [aMenuButton objectForKey:kButtonColorKey];
}
[self.scrollViewButtonView addSubview:aButton];
anXOffset += kMenuButtonWidth;
}
}
}
self.scrollViewContentView = [UIButton buttonWithType:UIButtonTypeCustom];
self.scrollViewContentView.frame = CGRectMake(kScreenOrigin, kScreenOrigin, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds));
if (![Utilities isIOS7orAbove]) {
[self.scrollViewContentView addTarget:self action:#selector(cellHighlighted) forControlEvents:UIControlEventTouchDown];
[self.scrollViewContentView addTarget:self action:#selector(cellCancelHighlight) forControlEvents:UIControlEventTouchDragExit];
}
[self.scrollViewContentView addTarget:self action:#selector(selectCell:) forControlEvents:UIControlEventTouchUpInside];
self.scrollViewContentView.backgroundColor = [UIColor whiteColor];
UIImage *aBGHighlightedImage = nil;
if ([Utilities isIOS7orAbove]) {
aBGHighlightedImage = [UIImage imageNamed:kCellHighlightedImageIOS7];
} else {
aBGHighlightedImage = [UIImage imageNamed:kCellHighlightedImageIOS6];
}
[self.scrollViewContentView setBackgroundImage:[aBGHighlightedImage stretchableImageWithLeftCapWidth:11.0f topCapHeight:0] forState:UIControlStateHighlighted];
[self.scrollView addSubview:self.scrollViewContentView];
[self.scrollViewContentView addSubview:self.imageView];
[self.scrollViewContentView addSubview:self.textLabel];
[self.scrollViewContentView addSubview:self.detailTextLabel];
}
- (void)prepareForReuse {
[super prepareForReuse];
self.scrollViewContentView.enabled = YES;
[self.scrollView setContentOffset:CGPointZero animated:NO];
}
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath {
MyTableViewCell *aCell = (MyTableViewCell *)[iTableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (!aCell) {
aCell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"CellIdentifier" andMenuButtonDetails:aMenuButtons];
}
// Set data on cell now
return aCell
}
Let me know if there is something I'm missing here, but it seems like you're adding a ton of complexity to your class for no reason. Are you familiar with UICollectionView?
Here's an example implementation (which scrolls horizontally):
#interface asdf () <UICollectionViewDataSource, UICollectionViewDelegate>
#property (strong, nonatomic) UICollectionView *collectionView;
#end
#implementation asdf
- (id)init
{
self = [super init];
if (self)
{
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.collectionViewLayout];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.view addSubview:self.collectionView];
NSString *className = NSStringFromClass([UICollectionViewCell class]);
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:className];
}
return self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.collectionView.frame = self.view.bounds;
}
- (UICollectionViewLayout *)collectionViewLayout
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.minimumInteritemSpacing = 0;
layout.minimumLineSpacing = 0;
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
return layout;
}
#pragma mark - UICollectionView
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 5;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *className = NSStringFromClass([UICollectionViewCell class]);
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:className forIndexPath:indexPath];
// This is for dequeuing
NSInteger tag = 12324;
UIView *view = [cell viewWithTag:tag];
if (view)
[view removeFromSuperview];
view = [[UIView alloc] initWithFrame:cell.bounds];
view.tag = tag;
// Add all of your subviews to the view property
[cell addSubview:view];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(collectionView.bounds.size.width, 50);
}
#end
I wrote this quickly as a sample, so it's not tailored specifically to what you're building, but this should give you a nice idea of how simple it is to implement a UICollectionView.
This answer may come across as random for what you're asking, but when possible, you should always try to use what Apple provides over what you would spend precious hours re-inventing the wheel w/ & likely experience random nuances like yours.

CollectionView memory VM:CoreAnimation memory allocated and abandoned

I have a some collectionViews and one table view that are in the same view controller. The rather strange problem is that when i scroll up-down I alway get memory increases.
Instruments show a lot of allocation of VM:CoreAnimation objects but I can't track them down (they are inside collectionView itself).
prepare for reuse is getting called inside the cells, I checked this.
Here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.receivedChannels = NO;
self.ItemsDict = [NSMutableDictionary new];
self.crtBatchSet = [NSMutableIndexSet new];
if ([[PSDeviceInfo sharedInstance] is_iPad]) {
self.epgWidth = EPG_WIDTH_IPAD;
} else {
self.epgWidth = EPG_WIDTH_IPHONE;
}
crtBatchSetSize = 0;
self.currentSelecteIndexOfDateCell = 0;
//size
self.widthDictionary = [NSMutableDictionary new];
self.centerXDictionary = [NSMutableDictionary new];
self.layout = [[MultipleLineLayout alloc] initWithWidthDictionary:self.widthDictionary andCenterXDictionary:self.centerXDictionary];
self.ItemsCollectionVIew.collectionViewLayout = self.layout;
self.ItemsCollectionVIew.showsHorizontalScrollIndicator = NO;
self.ItemsCollectionVIew.showsVerticalScrollIndicator = NO;
self.layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
[self.ItemsCollectionVIew registerClass:[ItemColectionCell class] forCellWithReuseIdentifier:#"ItemColectionCellID"];
[self.hoursCollectionView registerClass:[HoursCollectionViewCell class] forCellWithReuseIdentifier:#"HoursColectionCellID"];
[self.datePickerCollectionView registerClass:[DatePickerCollectionViewCell class] forCellWithReuseIdentifier:#"DatePickerColectionCellID"];
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView == self.ItemsCollectionVIew){
self.channelsTableView.contentOffset = CGPointMake(0, self.ItemsCollectionVIew.contentOffset.y);
self.hoursCollectionView.contentOffset = CGPointMake(self.ItemsCollectionVIew.contentOffset.x, 0);
}
if (scrollView == self.channelsTableView) {
self.ItemsCollectionVIew.contentOffset = CGPointMake(self.ItemsCollectionVIew.contentOffset.x,self.channelsTableView.contentOffset.y);
}
if (scrollView == self.hoursCollectionView) {
self.ItemsCollectionVIew.contentOffset = CGPointMake(self.hoursCollectionView.contentOffset.x,self.ItemsCollectionVIew.contentOffset.y);
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *channelCellID = #"ChannelTableCellID";
ChannelTableCell *cell = [tableView dequeueReusableCellWithIdentifier:channelCellID forIndexPath:indexPath];
cell.myIndexInTable = indexPath.row;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[cell getData];
return cell;
}
#pragma mark - UITableViewDelegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self.ItemsCollectionVIew reloadData];
}
#pragma mark - UICollectionViewDataSource Methods
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
if (collectionView == self.datePickerCollectionView || collectionView == self.hoursCollectionView) {
return 1;
}else{
if (self.receivedChannels) {
return totalNoChannels;
} else {
return 1;
}
}
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
if (collectionView == self.datePickerCollectionView) {
return DELTA_DAYS + 1;
}else if (collectionView == self.hoursCollectionView) {
return 48; //24 hours * 2
}else{
// if (collectionView == self.ItemsCollectionVIew){
NSArray *sectionItems = self.ItemsDict[#(section)];
if (sectionItems) {
// return sectionItems.count;
return 100;
} else {
return 100;
}
}
return 1;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
if (collectionView == self.datePickerCollectionView) {
static NSString *ItemCellID = #"DatePickerColectionCellID";
DatePickerCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ItemCellID forIndexPath:indexPath];
[self setDayAndDateforCell:cell at:indexPath];
[cell setBackgroundColor:[self getColorForCell:self.currentSelecteIndexOfDateCell == indexPath.row ? YES:NO]];
return cell;
}else if (collectionView == self.hoursCollectionView){
static NSString *ItemCellID = #"HoursColectionCellID";
HoursCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ItemCellID forIndexPath:indexPath];
cell.hourLabel.text = [self getTimeLineCellValuerFor:indexPath];
return cell;
} else{
// if (collectionView == self.datePickerCollectionView) {
static NSString *ItemCellID = #"ItemColectionCellID";
ItemColectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ItemCellID forIndexPath:indexPath];
NSArray *Items = self.ItemsDict[#(indexPath.section)];
if (indexPath.row >= Items.count) {
return cell;
}
MvpItem *prog = Items[indexPath.row];
[cell updateInfo:prog];
[cell setBackgroundColor:[self getColorForCell:NO]];
return cell;
}
}
#pragma mark - UICollectionViewDelegate Methods
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
if (collectionView == self.datePickerCollectionView) {
self.currentSelecteIndexOfDateCell = indexPath.row;
}
if (collectionView == self.ItemsCollectionVIew) {
[self pushDetailsatIndexPath:indexPath];
}
}
The code for the tableView cell is:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
[self.layer setBorderColor:[UIColor blackColor].CGColor];
[self.layer setBorderWidth:1.0f];
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)prepareForReuse{
self.thumbnailImage.image = nil;
self.channel = nil;
[self clearDelegate];
[super prepareForReuse];
}
- (void)dealloc
{
[self clearDelegate];
}
- (void)clearDelegate
{
NSString *url = self.channel.media_content.thumbPoster.url;
// [[ImageManager sharedInstance] removeDelegate:self forImgUrl:url];
[[TVManager sharedInstance] removeDelegate:self];
}
- (void)getData
{
[[TVManager sharedInstance] getChannelAndItemssForIndex:self.myIndexInTable forDateDelta:0 forDelegate:self];
}
- (void)didReceiveTotalNoChn:(NSInteger)totalChnNo{
return;
}
- (void)didReceiveChannel:(MvpChannel *)channel withItemss:(NSArray *)Itemss forDateDelta:(NSInteger)date withIndex:(NSUInteger)index{
if (index != self.myIndexInTable) {
return;
}
if ([self.channel isEqual:channel]) {
return;
}
self.channel = channel;
NSString *imgUrl = self.channel.media_content.thumbPoster.url;
// UIImage *img = [[ImageManager sharedInstance] getImageForUrl:imgUrl forIndex:self.myIndexInTable withDelegate:self];
// if (img) {
// self.thumbnailImage.image = img;
// }
}
#pragma mark - Image Delegate
- (void)didReceiveImage:(UIImage *)image forIndex:(NSInteger)index
{
if (index != self.myIndexInTable) {
return;
}
if (image) {
self.thumbnailImage.contentMode = UIViewContentModeScaleAspectFit;
self.thumbnailImage.image = image;
[self setNeedsLayout];
}
}
And inside the collectionViewCell:
#interface ItemColectionCell ()
#property (retain, nonatomic) UILabel *titleLabel;
#property (retain, nonatomic) UILabel *genreLabel;
#property (retain, nonatomic) UILabel *intervalLabel;
#end
#implementation ItemColectionCell //collection
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self.layer setBorderColor:[UIColor blackColor].CGColor];
[self.layer setBorderWidth:1.0f];
self.titleLabel = [[UILabel alloc] init];
self.genreLabel = [[UILabel alloc] init];
self.intervalLabel = [[UILabel alloc] init];
[self.titleLabel setBackgroundColor:[UIColor clearColor]];
[self.genreLabel setBackgroundColor:[UIColor clearColor]];
[self.intervalLabel setBackgroundColor:[UIColor clearColor]];
[self.titleLabel setTextColor:[UIColor whiteColor]];
[self.genreLabel setTextColor:[UIColor whiteColor]];
[self.intervalLabel setTextColor:[UIColor whiteColor]];
[self.titleLabel setFont:[UIFont fontWithName:#“cf-Bold" size:15]];;
[self.genreLabel setFont:[UIFont fontWithName:#“cf-Regular" size:11]];;
[self.intervalLabel setFont:[UIFont fontWithName:#“cf-Regular" size:11]];;
}
return self;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
- (void)prepareForReuse{
self.titleLabel.text = nil;
self.genreLabel.text = nil;
self.intervalLabel.text = nil;
[self.titleLabel removeFromSuperview];
[self.genreLabel removeFromSuperview];
[self.intervalLabel removeFromSuperview];
[super prepareForReuse];
}
- (void)updateInfo:(MvpItem*)item{
if (!item) {
return;
}
NSDateFormatter *startTimeFormat = [[NSDateFormatter alloc] init];
[startTimeFormat setDateFormat:#"hh:mm"];
NSDateFormatter *endTimeFormat = [[NSDateFormatter alloc] init];
[endTimeFormat setDateFormat:#"hh:mm a"];
NSString *startTime = [startTimeFormat stringFromDate:item.startTime];
NSString *endTime = [endTimeFormat stringFromDate:item.endTime];
self.titleLabel.frame = CGRectMake(10, 7, self.frame.size.width - 10, 15);
self.genreLabel.frame = CGRectMake(10, 20, self.frame.size.width - 10, 15);
self.intervalLabel.frame = CGRectMake(10, 32, self.frame.size.width - 10, 15);
self.titleLabel.text = item.title;
self.genreLabel.text = #“tewst”;
self.intervalLabel.text = [NSString stringWithFormat:#"%# - %#", startTime, endTime];
[self addSubview:self.titleLabel];
[self addSubview:self.genreLabel];
[self addSubview:self.intervalLabel];
}
What ca I do to solve this problem?
Did you try to remove the cell or heavy tasks triggered by displaying that cell when it did end displaying?
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
or
- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

Segmented Control change tableView datasource

UISegmentedControl changes tableView datasource.
After I described [myView addSubview:_tableView];
instead of [self.view addSubview:_tableView];,
daySegmentedControl process stopped working.
I have this code.
ViewController.m
#implementation ViewController
{
int _tableType;
NSArray *_data1;
NSArray *_data2;
}
#synthesize segment;
#synthesize daySegment;
#synthesize myView;
- (void)viewDidLoad
{
[super viewDidLoad];
_tableType = 1;
_data1 = #[#[#"A",#"B",#"C"]];
_data2 = #[#[#"D",#"E",#"F"]];
myView = [[UIView alloc]initWithFrame:CGRectMake(-1, 44, 340, 480)];
[self.view addSubview:myView];
myView.opaque = NO;
myView.backgroundColor = [UIColor colorWithWhite:1.0f alpha:0.0f];
[self.view bringSubviewToFront:myView];
[self segmentView];
[self daySegmentView];
[self dayTableView];
}
- (void)segmentView
{
NSArray *SegmentContent = [NSArray arrayWithObjects:#"View1",#"View2",nil];
segment = [[UISegmentedControl alloc] initWithItems:WDSegmentContent];
segment.frame = CGRectMake(-2, 20, 326, 25);
segment.selectedSegmentIndex = 0;
[segment addTarget:self action:#selector(WDSegmentAction:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:segment];
}
- (void)WDSegmentAction:(id)sender
{
switch (segment.selectedSegmentIndex){
case 0:
[self dayTableView];
break;
case 1:
[self dayTableView];
break;
default:
break;
}
}
- (void)daySegmentView
{
NSArray *daySegmentContent = [NSArray arrayWithObjects:#"A",#"D",nil];
daySegment = [[UISegmentedControl alloc] initWithItems:daySegmentContent];
daySegment.frame = CGRectMake(0, 0, 326, 25);
daySegment.selectedSegmentIndex = 0;
[daySegment addTarget:self action:#selector(daySegmentAction:) forControlEvents:UIControlEventValueChanged];
[myView addSubview:daySegment];
}
- (void)daySegmentAction:(id)sender
{
switch (segment.selectedSegmentIndex){
case 0:
_tableType = 1;
[self.tableView reloadData];
break;
case 1:
_tableType = 2;
[self.tableView reloadData];
break;
default:
break;
}
}
- (void)dayTableView
{
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 30, 320, 480)];
_tableView.dataSource = self;
_tableView.delegate = self;
[myView addSubview:_tableView];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_data1[section]count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *data;
if (_tableType == 1) {
data = _data1[indexPath.section][indexPath.row];
} else if (_tableType == 2){
data = _data2[indexPath.section][indexPath.row];
}
cell.textLabel.text = data;
return cell;
}
#end
Any idea on how I could fix it?
I used different approach for changing segments. Just for illustration:
in segment changed method:
[_tableView reloadData];
In your numberOfRowsInSection:
if(_segControl.selectedSegmentIndex == 0)
{
return [dataSourceOne count];
}else
{
return [dataSourceTwo count];
}
}
In your heightForRowAtIndexPath
if(_segControl.selectedSegmentIndex == 0) { //one
return 60;
} else { //two
return 70;
}
In your cellForRowAtIndexPath
if(_segControl.selectedSegmentIndex == 0) {
//generate and populate cell for type one
}else
{
//generate and populate cell for type two
}
Use daySegment.selectedSegmentIndex instead of segment.selectedSegmentIndex in
- (void)daySegmentAction:(id)sender

iOS How to create undefined UIControl in custom UITableViewCell

I'm trying to write a prototype UITableViewCell with title and undefined UIControl that we are setting in cellForRowAtIndexPath:
Now I have implementation for cell:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.contentView addSubview:self.titleLabel];
[self.contentView addSubview:self.control];
}
return self;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
[_titleLabel setBackgroundColor:[UIColor clearColor]];
_titleLabel.numberOfLines = 2;
[_titleLabel setFont:[UIFont fontWithName:#"Georgia-Italic" size:15]];
[_titleLabel setTextColor:RGBColor(51, 102, 153)];
[_titleLabel setTextColor:[UIColor darkGrayColor]];
}
return _titleLabel;
}
- (UIControl *)control{
if (!_control) {
_control = [[UIControl alloc] init];
[_control setBackgroundColor:[UIColor whiteColor]];
}
return _control;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGRect contentRect = [[self contentView] bounds];
self.titleLabel.frame = CGRectMake(10, 5, 85, contentRect.size.height-10);
self.control.frame = CGRectMake(100, 5, contentRect.size.width-105, contentRect.size.height-10);
[self.contentView bringSubviewToFront:self.control];
[self bringSubviewToFront: self.control];
}
And implemented cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellAddOrder";
ICControlCell *cell = (ICControlCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[ICControlCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
[cell setAccessoryType:UITableViewCellAccessoryNone];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
NSObject *cellContent = [self.cellList objectAtIndex:indexPath.row];
cell.titleLabel.text = ICLocalized([cellContent valueForKey:#"name"]);
switch ([[cellContent valueForKey:#"control"] intValue]) {
case 0: {
UITextField *textField = [[UITextField alloc] init];
textField.placeholder = ICLocalized([[cellContent valueForKey:#"name"] stringByAppendingString:#"_placeholder"]);
textField.delegate = self;
textField.returnKeyType = UIReturnKeyNext;
textField.autocapitalizationType = UITextAutocapitalizationTypeWords;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.text = [cellContent valueForKey:#"data"];
textField.tag = indexPath.row;
cell.control = textField;
}
break;
case 1:
case 2:
case 3: {
UISwitch *switchControl = [[UISwitch alloc] init];
[switchControl setOn:[[cellContent valueForKey:#"data"] boolValue]];
[switchControl addTarget:self
action:#selector(switchStateChanged:)
forControlEvents:UIControlEventValueChanged];
switchControl.tag = indexPath.row;
cell.control = switchControl;
}
break;
default:
break;
}
return cell;
}
But when I'm trying to test that controller controls for cell are not displaying, just title labels..
How can I handle that problem? Please help me
you should use different cell identifiers for different items for example if you have UITextField and UISwitch then you should use two identifiers because you are reusing the cell.So it should be the same type of cell to be reused.
Doc says:
You cannot use the UIControl class directly to instantiate controls.
So, you can just declare the UIControl variable the cell prototype class but set it to nil there. All the control related operations should be done from inside the delegate, because that is the place where you exactly know which class to use. So,
Don't initialize control in cell class snippet from 'control' property:
- (UIControl *)control{
return _control;
}
Cell's constructor should also not call addSubview for control. So,
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
[self.contentView addSubview:self.titleLabel];
}
return self;
}
Add background color setting in cell's layoutSubviews here:
- (void)layoutSubviews {
...
if (cell.control) {
[cell.control setBackgroundColor:[UIColor whiteColor]];
self.control.frame = CGRectMake(100, 5, contentRect.size.width-105, contentRect.size.height-10);
[self.contentView bringSubviewToFront:self.control];
[self bringSubviewToFront: self.control];
}
}
Add subview in the delegate's cellforrow method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
cell.control = textField;
[cell.contentView addSubview:cell.control];
...
}

Resources