How to Set iOS 13 Glyphs Programmatically

How to set iOS 13 glyphs programmatically

Replace:

UIImage(named: "square.and.arrow.up")

With:

UIImage(systemName: "square.and.arrow.up")

This is now documented in UIImage

How to use default iOS images?

Developers haven't direct access to these images. I mean that you can't initialise image object like this:

UIImage *image = [UIImage imageNamed:@"name_of_system_image"];

But you can display some of images by using system types. For example you could init UIBarButtonItem with system types that provides standard icons:

- (id)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action

Where UIBarButtonSystemItem provides such types:

UIBarButtonSystemItemDone,
UIBarButtonSystemItemCancel,

UIBarButtonSystemItemEdit,

UIBarButtonSystemItemSave,

UIBarButtonSystemItemAdd,

UIBarButtonSystemItemFlexibleSpace,

UIBarButtonSystemItemFixedSpace,

UIBarButtonSystemItemCompose,

UIBarButtonSystemItemReply,

UIBarButtonSystemItemAction,

UIBarButtonSystemItemOrganize,

UIBarButtonSystemItemBookmarks,

UIBarButtonSystemItemSearch,

UIBarButtonSystemItemRefresh,

UIBarButtonSystemItemStop,

UIBarButtonSystemItemCamera,

UIBarButtonSystemItemTrash,

UIBarButtonSystemItemPlay,

UIBarButtonSystemItemPause,

UIBarButtonSystemItemRewind,

UIBarButtonSystemItemFastForward,

UIBarButtonSystemItemUndo,

UIBarButtonSystemItemRedo,

UIBarButtonSystemItemPageCurl

Rendering Certain Character Glyph on iPhone

The problem is not the iPhone supports only certain Indic or do not support AAT fonts.
The iPhone support AAT table for sure.
The problem is the proper AAT font that you use is not included!!
U can have few glyph displayed because those ones are inlcude either in arialuni.ttf or helvetica.ttf. But those font do not have any OpenType or AAT tables.

I can confirm with picture what I state, I have a jailbreak iPhone and you can check flickr.com/photos/41161441@N03/ for picture for proper Khmer rendering, which is one of the most complex Indic script.

I explained the problem on modmyi.com web site forum.
http://www.modmyi.com/forums/general-iphone-chat/680094-indic-font-rendering-iphone-yes-working.html#post4897261

How to use SF Symbols in iOS 12 and below?

You can not use SFSymbols natively in iOS versions older than iOS 13 (see Apple's Human Interface Guidelines for SF Symbols).

However, if you are interested in using the graphics you can use the SFSymbols app to export SVG versions of the icon. Then use some graphics tool to convert them to PNG icons you can import into your asset catalog.

Screenshot how to export SVG from SFSymbols app on Mac.

iOS 13: How can I tweak the leading / descend / line height of a custom font in UIKit / SwiftUI

I know what you are asking as I have faced the same issues with custom fonts. I am going to offer two solutions. In my own project I went the way of your suggestion in overriding intrinsicContentSize and adding a padding multiplier for height and width. In my case the fonts were user facing so I had a struct that held all the relevant information. FYI Chalkduster is in the system and clips. I also believe that this is all due to the font file itself.

Solution 1:
Example:

struct UserFont{
var name : String
var displayName : String
var widthMultiplier : CGFloat
var heightMultiplier : CGFloat
}

Then in my UILabel I have it subclassed to use both of these metrics

@IBDesignable
class MultiplierUILabel: UILabel {
@IBInspectable var widthPaddingMultiplier : CGFloat = 1
@IBInspectable var heightPaddingMultiplier : CGFloat = 1
override var intrinsicContentSize: CGSize{
return CGSize(width: super.intrinsicContentSize.width * widthPaddingMultiplier, height: super.intrinsicContentSize.height * heightPaddingMultiplier)
}
}

This to me was the simplest implementation as I found the font and multiplier scale accordingly.

Solution 2:

You might be able to get the draw to occur slightly higher by measuring the glyph bounds and adjusting the origin y. For example this fixes the clipping on Chalkduster font that is included in the system.

@IBDesignable
class PaddingUILabel: UILabel {
override func drawText(in rect:CGRect) {
//hello
guard let labelText = text else { return super.drawText(in: rect) }
//just some breathing room
let info = boundsForAttrString(str: labelText, font: self.font!, kern: .leastNormalMagnitude)
let glyph = info.glyph
var newRect = rect
let glyphPadding = -(glyph.origin.y)
if glyphPadding - info.descent > 1 && info.descent != 0{
newRect.origin.y -= glyphPadding/2
}else{
if info.descent != 0{
newRect.origin.y += (info.descent - glyphPadding)/2
}
}
super.drawText(in: newRect)
}

func boundsForAttrString(str:String,font:UIFont,kern:CGFloat)->(glyph:CGRect,descent:CGFloat){
let attr = NSAttributedString(string: str, attributes: [.font:font,.kern:kern])
let line = CTLineCreateWithAttributedString(attr)
var ascent : CGFloat = 0
var descent : CGFloat = 0
var leading : CGFloat = 0

CTLineGetTypographicBounds(line, &ascent, &descent, &leading)
let glyph = CTLineGetBoundsWithOptions(line, .useGlyphPathBounds).integral
return (glyph,leading != 0 ? descent : 0)
}
}

Result of Solution 2:
System
System

PaddingUILabel using glyph bounds
PaddingUILabel

Getting a glyph boundingRect in draw#rect in UILabel

It turns out the answer to this question seems to be:

In fact, surprisingly or not, you basically have no access to glyph information in UILabel specifically.

So realistically you can't get those glyph "actual shapes" in UILabel.

In particular RobN. has pointed out that an investigation showed that in UILabel, _drawTextInRect:baselineCalculationOnly does the work and that is a big pile of ad hoc code.

A summary of the situation would seem to be that UILabel simply predates NSLayoutManager / Core Text and (as yet) just plain does not use those modern systems.

Only those modern systems give you this ...

Sample Image

... sort of access to glyph-by-glyph shapes.

iOS SDK - Programmatically generate a PDF file

A couple things...

First, there is a bug with CoreGraphics PDF generation in iOS that results in corrupted PDFs. I know this issue exists up to and including iOS 4.1 (I haven't tested iOS 4.2). The issue is related to fonts and only shows up if you include text in your PDF. The symptom is that, when generating the PDF, you'll see errors in the debug console that look like this:

<Error>: can't get CIDs for glyphs for 'TimesNewRomanPSMT'

The tricky aspect is that the resulting PDF will render fine in some PDF readers, but fail to render in other places. So, if you have control over the software that will be used to open your PDF, you may be able to ignore this issue (e.g., if you only intend to display the PDF on the iPhone or Mac desktops, then you should be fine using CoreGraphics). However, if you need to create a PDF that works anywhere, then you should take a closer look at this issue. Here's some additional info:

http://www.iphonedevsdk.com/forum/iphone-sdk-development/15505-pdf-font-problem-cant-get-cids-glyphs.html#post97854

As a workaround, I've used libHaru successfully on iPhone as a replacement for CoreGraphics PDF generation. It was a little tricky getting libHaru to build with my project initially, but once I got my project setup properly, it worked fine for my needs.

Second, depending on the format/layout of your PDF, you might consider using Interface Builder to create a view that serves as a "template" for your PDF output. You would then write code to load the view, fill in any data (e.g., set text for UILabels, etc.), then render the individual elements of the view into the PDF. In other words, use IB to specify coordinates, fonts, images, etc. and write code to render various elements (e.g., UILabel, UIImageView, etc.) in a generic way so you don't have to hard-code everything. I used this approach and it worked out great for my needs. Again, this may or may not make sense for your situation depending on the formatting/layout needs of your PDF.

EDIT: (response to 1st comment)

My implementation is part of a commercial product meaning that I can't share the full code, but I can give a general outline:

I created a .xib file with a view and sized the view to 850 x 1100 (my PDF was targeting 8.5 x 11 inches, so this makes it easy to translate to/from design-time coordinates).

In code, I load the view:

- (UIView *)loadTemplate
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ReportTemplate" owner:self options:nil];
for (id view in nib) {
if ([view isKindOfClass: [UIView class]]) {
return view;
}
}

return nil;
}

I then fill in various elements. I used tags to find the appropriate elements, but you could do this other ways. Example:

UILabel *label = (UILabel *)[templateView viewWithTag:TAG_FIRST_NAME];
if (label != nil) {
label.text = (firstName != nil) ? firstName : @"None";

Then I call a function to render the view to the PDF file. This function recursively walks the view hierarchy and renders each subview. For my project, I need to support only Label, ImageView, and View (for nested views):

- (void)addObject:(UIView *)view
{
if (view != nil && !view.hidden) {
if ([view isKindOfClass:[UILabel class]]) {
[self addLabel:(UILabel *)view];
} else if ([view isKindOfClass:[UIImageView class]]) {
[self addImageView:(UIImageView *)view];
} else if ([view isKindOfClass:[UIView class]]) {
[self addContainer:view];
}
}
}

As an example, here's my implementation of addImageView (HPDF_ functions are from libHaru):

- (void)addImageView:(UIImageView *)imageView
{
NSData *pngData = UIImagePNGRepresentation(imageView.image);
if (pngData != nil) {
HPDF_Image image = HPDF_LoadPngImageFromMem(_pdf, [pngData bytes], [pngData length]);
if (image != NULL) {
CGRect destRect = [self rectToPDF:imageView.frame];

float x = destRect.origin.x;
float y = destRect.origin.y - destRect.size.height;
float width = destRect.size.width;
float height = destRect.size.height;

HPDF_Page page = HPDF_GetCurrentPage(_pdf);
HPDF_Page_DrawImage(page, image, x, y, width, height);
}
}
}

Hopefully that gives you the idea.



Related Topics



Leave a reply



Submit