简体   繁体   中英

Why is my attributed string being displayed oddly?

I've been following the CS193P Stanford iOS development lectures, and on the second assignment, "Set," I just cannot figure out what is wrong with my program displaying an attributed string on a button. For some reason, when my string attempts to display 3 characters, it ends up showing up as 1 big character and 3 random other characters. Also many of the characters show up as black when I only have intended there to be red, green, and blue characters. I would greatly appreciate it if someone could build this project and help me figure out what is going on. I've spent about 4 hours trying to debug this. The source is at https://github.com/zhumatthew/MatchSet

The problem is under the set view controller for the second tab in the tab bar.

Thanks.

http://postimg.org/image/gs7qley3r/

#import "SetViewController.h"
#import "SetCardDeck.h"
#import "SetCard.h"

@interface SetViewController ()

@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;

@end

@implementation SetViewController

@synthesize deck = _deck;

- (Deck *)deck {
    if (!_deck) _deck = [[SetCardDeck alloc] init];
    return _deck;
}

- (void)updateUI {
    [super updateUI];
    for (UIButton *cardButton in self.cardButtons) {
        UIColor *foregroundColor;
        UIColor *strokeColor;

        SetCard *card = (SetCard *)[self.game cardAtIndex:[self.cardButtons indexOfObject:cardButton]];
        NSString *string = [[NSString alloc] init];
        for (int i = 0; i < card.number; i++) {
            string = [NSString stringWithFormat:@"%@%@", string, card.symbol];
        }
        if ([card.color isEqualToString:@"R"]) {
            foregroundColor = [UIColor redColor];
        } else if ([card.color isEqualToString:@"G"]) {
            foregroundColor = [UIColor greenColor];
        } else if ([card.color isEqualToString:@"B"]) {
            foregroundColor = [UIColor blueColor];
        }

        strokeColor = [foregroundColor copy];

        if ([card.shading isEqualToString:@"S"]) {
            foregroundColor = [foregroundColor colorWithAlphaComponent:1];
        } else if ([card.shading isEqualToString:@"H"]) {
            foregroundColor = [foregroundColor colorWithAlphaComponent:0.3];
        } else if ([card.shading isEqualToString:@"O"]) {
            foregroundColor = [foregroundColor colorWithAlphaComponent:0];
        }
        NSAttributedString *mat = [[NSAttributedString alloc] initWithString:string attributes:@{NSForegroundColorAttributeName:foregroundColor,NSStrokeWidthAttributeName:@-5,NSStrokeColorAttributeName:strokeColor}];
        [cardButton setAttributedTitle:mat forState:UIControlStateNormal];
        CGFloat red;
        CGFloat green;
        CGFloat blue;
        CGFloat alpha;
        [foregroundColor getRed:&red green:&green blue:&blue alpha:&alpha];
        NSLog(@"red:%f green:%f blue:%f alpha:%f index:%d",red,green,blue,alpha,[self.cardButtons indexOfObject:cardButton]);
        [strokeColor getRed:&red green:&green blue:&blue alpha:&alpha];
        NSLog(@"red:%f green:%f blue:%f alpha:%f ",red,green,blue,alpha);
        NSLog(@"%@",[mat string]);
        cardButton.selected = card.isFaceUp;
        cardButton.enabled = !card.isUnplayable;

        if (card.isFaceUp) {
            [cardButton setBackgroundColor:[UIColor lightGrayColor]];
        } else {
            [cardButton setBackgroundColor:[UIColor whiteColor]];
        }
    }
}

@end

There are two different issues, as far as I can see:

  • The button labels are truncated , so what you see as "3 random other characters" is the ellipsis (...). You have to enlarge the button or use a smaller font size. Perhaps also set the "Line Break" mode of the buttons to "Clip" instead of "Truncate ...".
  • On iOS 6 some characters (such as the "◼" symbol) are displayed as "Apple Color Emoji". This is a (controversially discussed) "feature", see eg https://devforums.apple.com/message/487463#487463 (requires Apple Developer login). As a consequence, attributes like color are ignored.

    The replacement by Emoji characters can be suppressed (from UILabel, UIFont and UTF-8 Triangle ) by appending the Unicode "Variation selector" U+FE0E:

     + (NSArray *)validSymbols { return @[@"◼\︎",@"●",@"▲"]; } 

    With that change, all your symbols are correctly displayed as intended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM