post Image
iOSでチラシっぽい価格レイアウトを再現してみた

概要

TwitterでフォロワーさんがUIStackViewで挑戦してたのを見かけた。

スレッドを遡ってみると、NSAttributedStringで実装できるんじゃないかという話があり、興味が湧いたので挑戦してみた。

作ったもの

文字のサイズ感は目見当。

chirashi.png

//
//  ViewController.swift
//  Price
//
//  Created by macneko on 2018/09/07.
//  Copyright © 2018年 macneko. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let label = UILabel()
        self.view.addSubview(label)

        label.frame = self.view.frame
        label.textAlignment = .center

        let fontSize: CGFloat = 80
        let font = UIFont.systemFont(ofSize: fontSize)
        let attributeText = NSMutableAttributedString(string: "各種¥(税込)280",
                                                      attributes: [.font: font, .foregroundColor: UIColor.red])
        // 各種
        attributeText.addAttributes([.font: UIFont.systemFont(ofSize: fontSize * 0.4),
                                     .baselineOffset: 2],
                                    range: NSRange(location: 0, length: 2))
        // ¥
        attributeText.addAttributes([.font: UIFont.systemFont(ofSize: fontSize * 0.6),
                                     .kern: -50],
                                    range: NSRange(location: 2, length: 1))
        // (税込)
        attributeText.addAttributes([.font: UIFont.systemFont(ofSize: fontSize * 0.2),
                                     .baselineOffset: (fontSize * 0.8) - (fontSize * 0.2) - 4],
                                    range: NSRange(location: 3, length: 4))
        // ()のベースライン調整
        attributeText.addAttributes([.baselineOffset: (fontSize * 0.8) - (fontSize * 0.2) - 3],
                                    range: NSRange(location: 3, length: 1))
        attributeText.addAttributes([.baselineOffset: (fontSize * 0.8) - (fontSize * 0.2) - 3],
                                    range: NSRange(location: 6, length: 1))
        label.attributedText = attributeText
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

説明

ソースコードを部分的に切り出して処理内容を説明する。

let fontSize: CGFloat = 80
let font = UIFont.systemFont(ofSize: fontSize)
let attributeText = NSMutableAttributedString(string: "各種¥(税込)280",
                                              attributes: [.font: font, .foregroundColor: UIColor.red])

はじめに attributeText に基本的な装飾と文字列を格納しておいて、装飾を変更したい部分をNSRangeで指定して、加工していく方法をとることにした。

// 各種
attributeText.addAttributes([.font: UIFont.systemFont(ofSize: fontSize * 0.4),
                             .baselineOffset: 2],
                            range: NSRange(location: 0, length: 2))

各種 の部分。
文字サイズは基本サイズの40%の大きさを指定。
や数字よりベースラインが少し下にずれて見えるので、.baselineOffset: 2 を指定して少し上にずらした。
ベースラインについては ラテン文字と欧文組版 をP14の図を参照。
雑に説明すると、.baselineOffset に正の数を与えると上に移動し、負の数を与えると下に移動する。

// ¥
attributeText.addAttributes([.font: UIFont.systemFont(ofSize: fontSize * 0.6),
                             .kern: -50],
                            range: NSRange(location: 2, length: 1))

の部分。
文字サイズは基本サイズの60%の大きさを指定。
.kern: -50 を指定して、次の文字の ( との字間を詰めた。
雑に説明すると、.kern (カーニング)は当該文字と次の文字の文字間のアキを詰める設定。
なお、パーレンにはカーニングが適用されないっぽかったので、を前にもってきてカーニング設定をしている。

// (税込)
attributeText.addAttributes([.font: UIFont.systemFont(ofSize: fontSize * 0.2),
                             .baselineOffset: (fontSize * 0.8) - (fontSize * 0.2) - 4],
                            range: NSRange(location: 3, length: 4))

(税込) の部分。
文字サイズは基本サイズの20%の大きさを指定。
ベースラインは相対値で計算したものの、それだけではうまく揃わなかったので、微調整している。

// ()のベースライン調整
attributeText.addAttributes([.baselineOffset: (fontSize * 0.8) - (fontSize * 0.2) - 3],
                            range: NSRange(location: 3, length: 1))
attributeText.addAttributes([.baselineOffset: (fontSize * 0.8) - (fontSize * 0.2) - 3],
                            range: NSRange(location: 6, length: 1))

() の部分。
ベースラインが揃わなかったので、この部分だけさらに微調整した。

文字列ごとにNSAttributedStringKeyを指定していき、最後に結合する方法でも良かったんだけど、DTP的な手法のほうが手慣れているため、この方法にしてしまったがゆえに、すごくIllustratorやInDesignを触っている気分になった。

まとめ

参考

Mastering TextKit


『 Swift 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。