3

I am writing a geometry based app. At one point in the app, there will be a UITableView with some custom cells. These cells contain UILabels. Amid the text of some these labels, I want to insert symbols that look these two triangles: image
(source: wiley.com)

However, since I cannot find these symbols in any Apple fonts, is there a way to insert an image into the string in place of a symbol?

Here is a (very) rough idea of what I'm going for (the actual table will not be static):

image2

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Garrett
  • 5,580
  • 2
  • 31
  • 47

4 Answers4

4

Ok, I get what you're trying to do. The key, I think, is to just keep adding controls to your cell, calculating the width as you go along.

First, I'd suggest a data structure to hold your cell contents. A simple array will do the job. I generally do this stuff as an ivar:

@interface LabelWithImagesViewController ()
{
    NSMutableArray *_cells;
}
@end

Then fill this array with the text and images you want. I'm doing a single row, but you can repeat for every row you need.

- (void)viewDidLoad
{
    [super viewDidLoad];

    _cells = [[NSMutableArray alloc] init];

    [_cells addObject:[[NSArray alloc] initWithObjects:
                       [UIImage imageNamed:@"triangle.png"],
                       @"CAT",
                       [UIImage imageNamed:@"semiequal.png"],
                       [UIImage imageNamed:@"triangle.png"],
                       @"DOG",
                       @"  If",
                       [UIImage imageNamed:@"triangle1.png"],
                       @"then",
                       [UIImage imageNamed:@"triangle2.png"],
                       nil]];
}

And then, you need to create your cell:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return _cells.count;
}

#define kEquationTag 100
#define kCellHeight 44

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"equationCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    UIView *equationContainer;

    if (cell == nil)
    {
        // if we don't have a cell create it, including the frame to hold our custom stuff

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        equationContainer = [[UIView alloc] initWithFrame:cell.contentView.bounds];
        equationContainer.tag = kEquationTag;
        [cell.contentView addSubview:equationContainer];
    }
    else
    {
        // if we are dequeing one that already exists, let's get rid of the old custom stuff

        equationContainer = [cell.contentView viewWithTag:kEquationTag];
        for (UIView *view in equationContainer.subviews)
        {
            [view removeFromSuperview];
        }
    }

    // Configure the cell...

    NSArray *cellContents = [_cells objectAtIndex:indexPath.row];

    NSUInteger x = 0;
    UIFont *font = [UIFont systemFontOfSize:12.0];

    for (NSObject *obj in cellContents)
    {
        if ([obj isKindOfClass:[NSString class]])
        {
            NSString *text = (NSString *)obj;
            CGSize size = [text sizeWithFont:font];
            UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x, (kCellHeight - size.height)/2.0, size.width, size.height)];
            label.text = text;
            label.font = font;
            [equationContainer addSubview:label];
            x += size.width;
        } 
        else if ([obj isKindOfClass:[UIImage class]])
        {
            UIImage *image = (UIImage *)obj;
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(x, (kCellHeight - image.size.height) / 2.0, image.size.width, image.size.height)];
            imageView.image = image;
            [equationContainer addSubview:imageView];
            x += image.size.width;
        }
    }

    return cell;
}

This yields:

enter image description here

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Awesome! That's exactly the answer I was looking for. Just one issue, the images I imported are way too big. What size did you make your images? – Garrett Jul 09 '12 at 21:33
2
  1. Make a UILabel and use instances of that UILabel for each letter.
  2. Use some geometry logic about the rect of the image view to place the letters regardless of size...such as

        UILabel *aLetterLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 35, 35)];
        aLetterLabel.text = @"A";
    
        //centered top
        aLetterLabel.frame = CGRectMake((shapeImage.frame.origin.x +  (shapeImage.frame.size.width/2)), shapeImage.frame.origin.y, 35, 35);
    
        //centered
        aLetterLabel.frame = CGRectMake((shapeImage.frame.origin.x + (shapeImage.frame.size.width/2)), (shapeImage.frame.origin.y + (shapeImage.frame.size.height/2)), 35, 35);
    
        //cenetered bottom
        aLetterLabel.frame = CGRectMake((shapeImage.frame.origin.x + (shapeImage.frame.size.width/2)), (shapeImage.frame.origin.y+(shapeImage.frame.size.height-35)), 35, 35);
    
        //left center align
        aLetterLabel.frame = CGRectMake(shapeImage.frame.origin.x, (shapeImage.frame.origin.y + (shapeImage.frame.size.height/2)), 35, 35);
    

Wrote these up really fast as a proof of concept...feel free to revise, etc.

Eric Welander
  • 560
  • 4
  • 11
  • Is there an alternative to creating so many UILabels? That seems like it will be incredibly inefficient, especially in a UITableViewCell. – Garrett Jul 09 '12 at 18:20
  • If you really want to have them in a Table View, I would say you need to make images with the letters pre rendered in for those shapes... – Eric Welander Jul 09 '12 at 18:24
  • If you could somehow work with these outside of a table view, a UILabel is a very lightweight UIKit element from what I understand, so I would't worry about it. My only fear is the tableview dequeueing cells would cause lots of problems hear, especially with different shapes and label configs – Eric Welander Jul 09 '12 at 18:25
2

You can create your own font with the exact symbols you need. Try this: http://glyphdesigner.71squared.com

Jesse Gumpo
  • 4,777
  • 1
  • 20
  • 29
  • This looks great! If I could set two answers as correct I would pick this one as well. If it wasn't for the price tag this would definitely be my preferred option. – Garrett Jul 09 '12 at 21:38
  • 50% off at the moment! – jowie Aug 28 '14 at 09:28
  • Actually, I take that back... Glyph Designer is for bitmap fonts, i.e. bitmap games, like a sprite sheet. They are incompatible with native iOS text components and cannot be loaded in as fonts! – jowie Aug 29 '14 at 12:47
  • I managed to get it to work with a trial version of Glyphs: http://www.glyphsapp.com/ – jowie Aug 29 '14 at 15:55
0

You can't insert an image in a UILabel. But you can add a UIImageView in the custom cells of your UITableView and then put a UIImage inside.

  • Yeah I was pretty sure that that would be the answer. But how can I wrap my text around the inserted image? – Garrett Jul 09 '12 at 17:54
  • 1
    @Garrett If you want text to wrap around images, you might want to investigate shifting to a UIWebView, where you create the HTML programmatically. – Rob Jul 09 '12 at 17:58
  • Yes, I think it's the better way to do that. – Jonathan Martin Jul 09 '12 at 18:00
  • @Garrett I'm sure there are better examples out there, but here is a simple example of how you fill a UIWebView with text and images: http://stackoverflow.com/questions/11247777/embedding-image-and-uilable-in-uiwebview/11248285#11248285. You'll have to design your own HTML string, but hopefully this points you in the right direction. – Rob Jul 09 '12 at 18:09
  • Another option worth looking into would be to include some font that already have the symbols into your bundle. – Alladinian Jul 09 '12 at 18:12
  • @RobertRyan I probably should have explained better, this image is just an example. My image will be provided in the app; it won't need to be retrieved from a server. – Garrett Jul 09 '12 at 18:15
  • @Alladinian I tried that but as I said I can't find that symbol in any fonts – Garrett Jul 09 '12 at 18:16
  • @Garrett You said _Apple_ fonts... I'm talking about any font that may do the job. I think there are numerous fonts that contain trigonometric/mathematical symbols available. – Alladinian Jul 09 '12 at 18:18
  • @Alladinian Where would I find other fonts, and how would I import them into my app? – Garrett Jul 09 '12 at 18:22
  • @Garret A good source for fonts: http://www.dafont.com | [How to add a custom font](http://stackoverflow.com/questions/9351264/how-to-use-custom-font-in-ios-apps) – Alladinian Jul 09 '12 at 18:24
  • @Garrett When you use a UIWebView, you don't need to retrieve the HTML from the web. If you look at the sample I provided, you can see how you can make your own HTML on the fly. It does have to retrieved from the web, nor even look like a web page. Lots of apps that have views with complex combinations of text, different text styles, images, etc. are using UIWebViews. – Rob Jul 09 '12 at 18:40
  • @RobertRyan Ok then, one last question: Is this a practical solution when the web view will be embedded in a tableView cell? – Garrett Jul 09 '12 at 18:42
  • @Garrett ah, probably not. (embedding a control that uses pan gestures in another that uses pan gestures is a hassle.) I didn't notice we were talking about tableview cells. But then again, a tableview cell is typically small enough that you probably don't have to engage in a lot of "wrapping text around the image". I guess we'd have to see an example of what the table cell would look like and what wrapping you'd need to have take place. – Rob Jul 09 '12 at 18:53
  • @RobertRyan I updated my question with an example of what it might look like – Garrett Jul 09 '12 at 19:12
  • @Garrett by embedding webview - only problem could be - that it will load with a little delay - and it is more noticable, when webview content uses images. Dont worry about gestures - you can set webview frame as big as its content, and it wont scroll. Good luck! – Guntis Treulands Jul 09 '12 at 20:33