your3i / your3i.github.io

0 stars 0 forks source link

SFSymbolsを理解する #16

Closed your3i closed 5 years ago

your3i commented 5 years ago

Ref: https://developer.apple.com/design/human-interface-guidelines/sf-symbols/overview/

SF Symbolsとは(What)

iOS13から提供される、iOSのシステムフォントSan Franciscoと一体化(integrate)できるアイコンのこと。 (1,500個以上ある)

一体化とは

テキストのweightやscaleに合わせて調整ができて、視覚上シムレスになるということ。

This correspondence lets you achieve precise weight matching between symbols and adjacent text, while supporting flexibility for different sizes and contexts.

どこまで調整できる

利用シーン

例えば、navigation bars, toolbars, tab bars, ... などのメニューのアイコン。 Actually...

Throughout the rest of your app, you can use a symbol everywhere you can use an image.

your3i commented 5 years ago

Custom Symbols

SF Symbolsに提供されてないアイコンを使いたい場合、自分のCustom Symbolsを作成できる。 SF Symbols appからアイコンのテンプレートをエクスポートして(a reusable, vector-based file format)、その上でカスタマイズした成果物は、SF Symbolsみたいにapp内利用できる。

image

Symbols for Use As-Is

Symbols for Use As-Isは一部のカスタマイズできないアイコンのこと。 Appleのtechnologiesと関係してるから。

image

注意点

your3i commented 5 years ago

懸念点

your3i commented 5 years ago

WWDC 2019 Introducing SF Symbols

Changes

Good

Details

Same baseline

image

All the Weights

Thinner weights have a distinctive, beautiful elegance, while the heavier ones strive to maintain detail and visibility.

6b1c9612690c877f7bb70712375b2e9d

Align vertically

image

Scales

There is a need for using symbols at different sizes when they are next to text, even if the text size doesn't change. This is something that many of us already do, depending on the amount of emphasis that the symbol may need, and how much space is available. So with iOS 13, we turned this into a system.

⬆️use it when you want to use symbols at different optical sizes but having the same point size with text

image

Where to use?

And in some places, like toolbars, your kit will do the right thing, and will pick the correct scale for the control automatically.

What does it mean?

It means you can use them with dynamic type, and everything just works image

your3i commented 5 years ago

some of the system icons are now symbols, too. So if you were using some of these, they will automatically use the new designs

before after
image image
  1. export the symbol from the app -> get template (SVG)
  2. very same template is directly used by Xcode as a source artifact

To provide

At least you have to provide...

Then...

if you want to support all dynamic-type styles...

Of course, you should take into consideration the typographic palette of your app

Summary

image

your3i commented 5 years ago

How to use in code

Use SF Symbols

copy name from SF Symbols app and just use it

slowerImageView.image = UIImage(systemName: "tortoise")
fasterImageView.image = UIImage(systemName: "hare")

use custom symbols

import svg file (made from template) to xcode asset catalog

let cupImage = UIImage(named: "teacup")

?

It turns out you can now have two images with the same name, but they are -- have a different type

Image with the same name - three version

image

what if I want both?

run my app on iOS 12 or earlier, and I get the old image, the bitmap image in this case. And if I run my app on iOS 13 or later

no need to write any write any version-checking code

If you do want to use the old image on iOS 13 or later, you have to duplicate or rename it

How to configure the appearance

// Set scales
let configuration = UIImage.SymbolConfiguration(scale: .large)
imageView.preferredSymbolConfiguration = configuration
// Symbols are typographic in nature, and it reflects in how you configure them

// typographic points, not screen points
let headlineConfig = UIImage.SymbolConfiguration(pointSize: 23.0f, weight: .medium)

// you can always add a scale
let annotationConfig = UIImage.SymbolConfiguration(pointSize: 17.0f, scale: .small)

So for symbols, you have to let go of describing the image using a dimension. You have to use the symbol points, and you can think of it as a piece of text.

Using a text style to configure a symbol

The symbol will behave according to the dynamic text style rules.

Why not use width & height to configure a symbol?

not constrain the symbol image at all, and have it be its natural size

your3i commented 5 years ago

Work with any font

titleLabel.font = style.titleFont()

let configuration = UIImage.SymbolConfiguration(font: titleLabel.font, scale: .large)
titleImage.preferredSymbolConfiguration = configuration

it works with system fonts. It works with dynamic type fonts, but it also works with custom fonts

How to change configurations: combine configurations

configurations are immutable, you have to combine them.

let boldLargeConfig = UIImage.SymbolConfiguration(weight: .bold, scale: .large)
let smallConfig = UIImage.SymbolConfiguration(scale: .small)

let config = boldLargeConfig.applying(smallConfig)
your3i commented 5 years ago

Layout

center alignment (no difference for symbols)

UIKit take the typographic information in the symbol and use it to properly visually align the symbol.So the center is optically and not absolute, but you don't have to do anything.

baseline alignment

align the symbol to the first line of a multiple-line text.

up until now, it would be a bit hard to make this happen for symbols, we can just baseline align, and that's it

Inspect the baseline

let chevron = UIImage(systemName: "person.square")

// the offset to the baseline from the bottom of the image
if let offset = chevron.baselineOffsetFromBottom {

}

They have the same size, and they share the same baseline. image

you can see that expressing the offset from the bottom means that going up is a positive offset and going down is a negative offset. It also means that it's valid for an image to have a baseline that is outside of its bounds, in this case, the chevron.

add baselines to images

// You can add baselines to any image
// Important: baseline offsets are in screen points.

let avatarImage: UIImage?
if let loadedImage = AvatarCache.load(forUser: user.id) {
  // give the avatar a baseline
  avatarImage = loadedImage.withBaselineOffsetFromBottom(3.5f)
} else {
  avatarImage = UIImage(systemName: "person.square")
}

image

Horizontal alignments

you do this by specifying an offset that you want to align to, and then center the images on that offset then you can go from that offset to the text, or from the edge to the text So you should actually center align, even horizontally, the images instead of applying a leading or a trailing constraint there. image

spec

it's probably a good idea to start with center alignment image

Buttons

all buttons in UIKit come with a preset symbol configuration

That means that it reacts to dynamic type changes, has a body text style, and a large scale.

// System buttons have a default configuration of: .body, .large

let watchImage = UIImage(systemName: "stopwatch")
let startButton = UIButton.system(image: watchImage, target: self, action: #selector(startTimer))

create a system button with any symbol image (custom or SF Symbol)

create your own system buttons that looked exactly the same, with your own symbol image?

we added some, an initializer on UIButton that allows you to create a system button with any symbol image.

Regular buttons

A regular button comes with a medium-scale preset.

// Buttons have a default configuration of .medium
// use setPreferredSymbolConfiguration() to change

let checkButton = UIButton(type: .custom)
checkButton.setImage(UIImage(systemName: "check"), forState: .normal)

let config = UIImage.SymbolConfiguration(textStyle: .caption, scale: .small)
button.setPreferredSymbolConfiguration(config, forState: .normal)

Bar buttons

bar buttons come with the preset configuration. And in any non-compact size class, like in portrait mode on your phone, the configuration will be large. If you then rotate your phone, and end up in a compact size class, we will change that configuration on the button to be medium. And this will call the symbol to slightly be smaller, and to fit perfectly in the more compact bars

no need to provide a secondary image, it will scale using the built-in symbol scales.

your3i commented 5 years ago

Rendering modes

Symbol has an intrinsic mode, but no intrinsic color, no color data built into it. Use tint color to render the symbol.

.renderingImage = .automatic

image

your3i commented 5 years ago

Draw an image in a graphic context

let cupImage = UIImage(named: "teacup")
let configuration = UIImage.SymbolConfiguration(pointSize: 34.0f, weight: .bold)
let largeCupImage = cupImage.withConfiguration(configuration) // specify configuration
let receipt = UIGraphicsImageRenderer(size: receiptSize).image {
  // ...

  cupImage.draw(at: .zero) // use natural size of the image (let the image decide how large it wourd be)

  //...
}
your3i commented 5 years ago

Use symbols in text (NSTextAttachment)

This API inspects the string around the symbol and configure the symbol's point size, weight, color, ...

image

image

Tinting images (*)

image

// Tintint images

let heartImage = UIImage(systemName: "heart.fill")
let redHeartImage = heartImage.withTintColor(.redColor, renderingMode: .alwaysOriginal)

And before, you would probably have to rasterize an image, and render into a graphics context, and then apply a color.You don't have to do that anymore.

your3i commented 5 years ago

Summary

image

So try to avoid rasterizing images, especially symbol images.

symbols also really shine because of dark tint color