cs193p – Assignment #2 Task #6

Please note, this blog entry is from a previous course. You might want to check out the current one.

Instead of drawing the cards in the classic form (we’ll do that next week), we’ll use these three characters ▲ ● ■ and use attributes in NSAttributedString to draw them appropriately (i.e. colors and shading).

In story board change the title of the buttons from plain to attributed. Inside the update function generate an attributed strong from the card contents. Check if the current card is a set card and update the attributes using updateAttributedString:withAttributesOfCard:, which we will create next. Finally set the adjusted title off the button:

- (void)updateUI
        NSAttributedString *title = [[NSAttributedString alloc] initWithString:card.contents];
        if ([card isKindOfClass:[SetCard class]]) {
            SetCard *setCard = (SetCard *)card;
            title = [self updateAttributedString:title withAttributesOfCard:setCard];
        [cardButton setAttributedTitle:title forState:UIControlStateNormal];

First create a mutable copy of the attributed string and find the range of the symbol (which is actually a complete word at the moment). If it is found find the character we want to display for the symbol (note that the symbol name does not really match the chosen symbol, which does not matter for now).

Now generate a mutable dictionary which will be used to hold the attributes. First add the color according to the card color.

For shading change the stroke and adjust if the inside should be filled. For “stripped” the color for the foreground (which is the inside of the symbol) needs to be set as stroke color, and the foreground color is lightened up.

The symbol needs to be repeated according to the number of symbols for the card.

Finally text representation of the symbol is exchanged for the character representation colored and shaded correctly:

- (NSAttributedString *)updateAttributedString:(NSAttributedString *)attributedString withAttributesOfCard:(SetCard *)card
    NSMutableAttributedString *mutableAttributedString = [attributedString mutableCopy];    
    NSRange range = [[mutableAttributedString string] rangeOfString:card.symbol];
    if (range.location != NSNotFound) {
        NSString *symbol = @"?";
        if ([card.symbol isEqualToString:@"oval"]) symbol = @"●";
        if ([card.symbol isEqualToString:@"squiggle"]) symbol = @"▲";
        if ([card.symbol isEqualToString:@"diamond"]) symbol = @"■";       
        NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];       
        if ([card.color isEqualToString:@"red"])
            [attributes setObject:[UIColor redColor] forKey:NSForegroundColorAttributeName];
        if ([card.color isEqualToString:@"green"])
            [attributes setObject:[UIColor greenColor] forKey:NSForegroundColorAttributeName];
        if ([card.color isEqualToString:@"purple"])
            [attributes setObject:[UIColor purpleColor] forKey:NSForegroundColorAttributeName];
        if ([card.shading isEqualToString:@"solid"])
            [attributes setObject:@-5 forKey:NSStrokeWidthAttributeName];
        if ([card.shading isEqualToString:@"striped"])
            [attributes addEntriesFromDictionary:@{
                     NSStrokeWidthAttributeName : @-5,
                     NSStrokeColorAttributeName : attributes[NSForegroundColorAttributeName],
                     NSForegroundColorAttributeName : [attributes[NSForegroundColorAttributeName] colorWithAlphaComponent:0.1]
        if ([card.shading isEqualToString:@"open"])
            [attributes setObject:@5 forKey:NSStrokeWidthAttributeName];
        symbol = [symbol stringByPaddingToLength:card.number withString:symbol startingAtIndex:0];
        [mutableAttributedString replaceCharactersInRange:range
                                     withAttributedString:[[NSAttributedString alloc] initWithString:symbol
    return mutableAttributedString;

The complete code is available on github.


Leave a Reply

Your email address will not be published.