UA-17470720-3

Jump to content


Photo
- - - - -

Add required asterisk to cells


  • Please log in to reply
34 replies to this topic

#1 Kyle Slattery

Kyle Slattery

    Jr. Member

  • STV 2.0
  • PipPip
  • 24 posts
Reputation: 0
Neutral

Posted 04 March 2011 - 09:00 AM

Hello,

I'd like to add a required asterisk to all cell types, but I'm not quite sure of the best way to do this. If I was just customizing a specific type of cell, I could subclass it and implement it there, but since I want it to apply to all cells, it's a little trickier. Basically I want it to look like this:

Posted Image

Since it's a different color, I need to use a separate label, unfortunately. Any thoughts on what the best way to accomplish this is?

Thanks!

#2 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 05 March 2011 - 12:45 AM

Hi Kyle,

The easiest way I can think of is to add an asterisk UILabel to the cell in the didLayoutSubviewsForCell delegate method (STV 2.0 and later). Here is some sample code:

- (void)tableViewModel:(SCTableViewModel *)tableViewModel 
  didLayoutSubviewsForCell:(SCTableViewCell *)cell 
  forRowAtIndexPath:(NSIndexPath *)indexPath
{
 if(cell.valueRequired)
 {
  UILabel *asteriskLabel;
  NSString *asteriskString = @"*";
 
  // check if asteriskLabel already exists (in case cell is being reused/redisplayed)
  asteriskLabel = (UILabel *)[cell.contentView viewWithTag:100];
  if(!asteriskLabel)
  {
   asteriskLabel = [[UILabel alloc] init];
   asteriskLabel.tag = 100;
   asteriskLabel.textColor = [UIColor redColor];

   // align to your own preference
   CGRect asteriskLabelFrame = cell.textLabel.frame;
   asteriskLabelFrame.origin.x += cell.textLabel.frame.size.width;
   asteriskLabelFrame.size.width = 
	[asteriskString sizeWithFont:asteriskLabel.font].width;
   asteriskLabel.frame = asteriskLabelFrame;

   [cell.contentView addSubview:asteriskLabel];
   [asteriskLabel release];
  }
  asteriskLabel.text = asteriskString;
 }
}

Please tell me if this works well for you.

#3 Kyle Slattery

Kyle Slattery

    Jr. Member

  • STV 2.0
  • PipPip
  • 24 posts
Reputation: 0
Neutral

Posted 07 March 2011 - 11:42 AM

Hm, it does work, but only for the first cell in a section. I added a breakpoint in the method, and it's definitely getting run multiple times, but for whatever reason, it's not being applied to all of the cells:

Posted Image

(All of those are marked with valueRequired = YES)

Thanks for your help so far!

#4 Kyle Slattery

Kyle Slattery

    Jr. Member

  • STV 2.0
  • PipPip
  • 24 posts
Reputation: 0
Neutral

Posted 07 March 2011 - 11:44 AM

Also, if I remove valueRequired from the first cell of the section, it still doesn't show on the following items.

#5 Kyle Slattery

Kyle Slattery

    Jr. Member

  • STV 2.0
  • PipPip
  • 24 posts
Reputation: 0
Neutral

Posted 07 March 2011 - 11:47 AM

Sorry to keep adding more posts, but I noticed this, all the cells after the first on in the section have a frame of 0,0,0,0:

<UILabel: 0x4c53920; frame = (0 0; 0 0); text = 'Marque'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x4c53890>>


#6 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 07 March 2011 - 12:13 PM

Hi Kyle,

It turns out that accessing cell.textLabel.frame in the willDisplayCell method is not always reliable, as apparently this value is sometimes reset to {0,0,0,0} after the cell is displayed (one of the mysteries of UITableView! :) ). The correct way (which happens to be more efficient too) is to implement the above code in the didLayoutSubviewsForCell method instead, which is only available starting STV 2.0. I've updated the above code to reflect that.

#7 Kyle Slattery

Kyle Slattery

    Jr. Member

  • STV 2.0
  • PipPip
  • 24 posts
Reputation: 0
Neutral

Posted 07 March 2011 - 12:20 PM

That works great, thanks so much for your help! Sensible TableViews has already saved me a bunch of time, it's a great product!

#8 Kyle Slattery

Kyle Slattery

    Jr. Member

  • STV 2.0
  • PipPip
  • 24 posts
Reputation: 0
Neutral

Posted 07 March 2011 - 12:53 PM

So, this is working great--however for a custom cell I built (subclass of SCSwitcherCell), it's not laying out properly:

Posted Image

This makes sense--in my subclass, I'm doing the customization to add the image in layoutSubviews. However, I'm calling [super layoutSubviews] at the beginning of this method, and since that's what calls the delegate method, it's causing the frame to be incorrect. Is there a better place for me to put the customizations, other than layoutSubviews, so this won't happen?

-Kyle

#9 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 07 March 2011 - 01:22 PM

Hi Kyle,

Please insert the following code at the end of your layoutSubviews method:

if([self.ownerTableViewModel.delegate conformsToProtocol:@protocol(SCTableViewModelDelegate)]
	   && [self.ownerTableViewModel.delegate respondsToSelector:@selector(tableViewModel:didLayoutSubviewsForCell:forRowAtIndexPath:)])
	{
		NSIndexPath *indexPath = [self.ownerTableViewModel indexPathForCell:self];
		[self.ownerTableViewModel.delegate tableViewModel:self.ownerTableViewModel didLayoutSubviewsForCell:self
										forRowAtIndexPath:indexPath];
	}

I also think we should encapsulate this code in a method so that it can be easily called instead of writing all this code. Please tell me if this works for you.

#10 Kyle Slattery

Kyle Slattery

    Jr. Member

  • STV 2.0
  • PipPip
  • 24 posts
Reputation: 0
Neutral

Posted 07 March 2011 - 01:27 PM

Yup, that works :). I also had to move the frame setting part of didLayoutSubviewsForCell out of the if(!asteriskLabel) statement, so it would reset the frame as needed.

#11 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 07 March 2011 - 01:37 PM

Great! Thanks Kyle for updating us :)

#12 codebonbon

codebonbon

    Advanced Member

  • STV 3.0 Pro
  • PipPipPipPipPip
  • 181 posts
Reputation: 8
Good

Posted 19 March 2011 - 01:19 PM

Hi Tarek!

Tried doing this in the detailView of my entity but without succes. Am i missing something?

Thamks!

- (void)tableViewModel:(SCTableViewModel *) tableViewModel 
detailViewWillAppearForSectionAtIndex:(NSUInteger) index 
withDetailTableViewModel:(SCTableViewModel *) detailTableViewModel
{
	NSManagedObjectContext *managedObjectContext = [(AppDelegate_Shared *)[UIApplication sharedApplication].delegate managedObjectContext];
	
	if ([[managedObjectContext insertedObjects] count] > 0) {
		
		for (int i=0; i<detailTableViewModel.sectionCount; i++) {
			SCTableViewSection *section =  [detailTableViewModel sectionAtIndex:i];
			
			for (int j=0; j<section.cellCount; j++) {
				SCTableViewCell *cell = [section cellAtIndex:j];
				
				if(cell.valueRequired)
				{
					UILabel *asteriskLabel;
					NSString *asteriskString = @"*";
					
					// check if asteriskLabel already exists (in case cell is being reused/redisplayed)
					asteriskLabel = (UILabel *)[cell.contentView viewWithTag:100];
					if(!asteriskLabel)
					{
						asteriskLabel = [[UILabel alloc] init];
						asteriskLabel.tag = 100;
						asteriskLabel.textColor = [UIColor redColor];
						
						// align to your own preference
						CGRect asteriskLabelFrame = cell.textLabel.frame;
						asteriskLabelFrame.origin.x += cell.textLabel.frame.size.width;
						asteriskLabelFrame.size.width = 
						[asteriskString sizeWithFont:asteriskLabel.font].width;
						asteriskLabel.frame = asteriskLabelFrame;
						
						[cell.contentView addSubview:asteriskLabel];
						[asteriskLabel release];
					}
					asteriskLabel.text = asteriskString;
				}
			}
		}
	}
}


#13 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 19 March 2011 - 04:36 PM

Hi Harold,

You must put the code in the didLayoutSubviewsForRowAtIndexPath (SCTableViewModelDelegate) or the didLayoutSubviewsForCell (SCTableViewCellDelegate) methods, as shown here: http://www.sensiblec...cells.html#2094

didLayoutSubviews is the only place where you are able to modify the frames of the cell's subviews. Good luck!
  • Geoffrey Alexander, Patrick Scheips, David DelMonte and 2 others like this

#14 codebonbon

codebonbon

    Advanced Member

  • STV 3.0 Pro
  • PipPipPipPipPip
  • 181 posts
Reputation: 8
Good

Posted 20 March 2011 - 01:40 PM

Hi Tarek!

Tried this but the asterisk doesn't show. Even though my property definition required is set to TRUE.


SCClassDefinition *adresseClassDef = [SCClassDefinition definitionWithEntityName:@"Adresse"
withManagedObjectContext:managedObjectContext
withPropertyNames:[NSArray arrayWithObjects:@"rue", @"ville", @"province",@"pays",@"codePostal",@"type",@"note", nil]];
adresseClassDef.uiElementDelegate = self;
SCPropertyDefinition *ruePropertyDef = [adresseClassDef propertyDefinitionWithName:@"rue"];
ruePropertyDef.autoValidate = FALSE;
ruePropertyDef.required = TRUE;

As you can see the rue property definition is required but still the asterisk does not show.

Thanks!

Harold

#15 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 20 March 2011 - 01:47 PM

Hi Harold,

Are you sure the didLayoutSubviewsForCell method is being called? You might have forgotten to conform to the SCTableViewCellDelegate protocol. Please post some more code if you're still stuck.

#16 codebonbon

codebonbon

    Advanced Member

  • STV 3.0 Pro
  • PipPipPipPipPip
  • 181 posts
Reputation: 8
Good

Posted 20 March 2011 - 02:09 PM

Hi Tarek!

It does get called but not for my detail view properties. Below my hierachy:

House --> Adress.Street

House as a 1 to 1 relationship with adress. Adress has a street property (rue in french).

Hope this helps.

Thanks!
  • Tarek likes this

#17 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 20 March 2011 - 03:43 PM

I am not sure I am following :) Is this a project you can send me Harold?
  • Tarek likes this

#18 codebonbon

codebonbon

    Advanced Member

  • STV 3.0 Pro
  • PipPipPipPipPip
  • 181 posts
Reputation: 8
Good

Posted 20 March 2011 - 10:29 PM

Hi Tarek!

Sent you my project via the support e-mail. Hope this help.

Thanks!
  • Tarek likes this

#19 Tarek

Tarek

    Forum Admin

  • Administrators
  • 3670 posts
Reputation: 452
Popular

Posted 25 March 2011 - 10:23 PM

Hi Harold,

Thanks for sending in your code. The method is not being called for your detail views because you need to assign a delegate for the detail models. For an example illustrating the concept of assigning delegates for detail models, please refer to this post: http://www.sensiblec...cells.html#2172

Please tell me if you need any more help. Thanks!

#20 codebonbon

codebonbon

    Advanced Member

  • STV 3.0 Pro
  • PipPipPipPipPip
  • 181 posts
Reputation: 8
Good

Posted 05 August 2011 - 05:56 AM

Hi Tarek!

There seems to be a an issue with the first detail view cell when it's of type SCobjectCell. This cell represents a 1 to 1 core data relationship that is not optional. The cell.textLabel.text is nil even though the property definition specifies a title.


- (void)viewDidLoad 
{

[super viewDidLoad];

...

entityPropertyDef = [homeClassDef propertyDefinitionWithName:@"address"];
			entityPropertyDef.attributes = [SCObjectAttributes  attributesWithObjectClassDefinition:adresseClassDef];
			entityPropertyDef.title = NSLocalizedString( @"Address",@"Address");
		
...

}

- (void)tableViewModel:(SCTableViewModel *)tableViewModel 
didLayoutSubviewsForCell:(SCTableViewCell *)cell 
	 forRowAtIndexPath:(NSIndexPath *)indexPath;
{

	DLog(@" cell.boundPropertyName:%@", cell.boundPropertyName);

	if(cell.valueRequired)
	{
		UILabel *asteriskLabel;
		NSString *asteriskString = @"*";
		
		// check if asteriskLabel already exists (in case cell is being reused/redisplayed)
		asteriskLabel = (UILabel *)[cell.contentView viewWithTag:100];
		if(!asteriskLabel)
		{
			asteriskLabel = [[UILabel alloc] init];
			asteriskLabel.tag = 100;
			asteriskLabel.textColor = [UIColor redColor];
			
			// align to your own preference
			CGRect asteriskLabelFrame = cell.textLabel.frame;
			asteriskLabelFrame.origin.x += cell.textLabel.frame.size.width;
			asteriskLabelFrame.size.width = 
			[asteriskString sizeWithFont:asteriskLabel.font].width;
			asteriskLabel.frame = asteriskLabelFrame;
			
			[cell.contentView addSubview:asteriskLabel];
			[asteriskLabel release];
		}
		asteriskLabel.text = asteriskString;
	}
}


Thanks again!




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users