Swift転職なら=>【LevTech】
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > CoreTextでTextViewの一文字の向きを変える(#2)

CoreTextでTextViewの一文字の向きを変える(#2)

前回の記事では向きを変える方法を失敗してしまいましたので、 今回は気持ちを切り替えて再調査。ルビをふるCoretextのサンプルがqiitaで紹介されていましたので、 そのサンプルを利用させて頂きトライしてみます

サンプル画像

さて、サンプルそのままだと面白くないので、本日6月から開始する自転車規制強化 にのっかったサンプル<自転車のだけ横に曲げる>にしてみます。(14歳以上が対象。自転車のイヤホン装着や片手走行、 酔っ払い運転、歩道運転、片手スマホ、、、、今まで誰もがやり通してきたことが「逮捕や補導の対象」となるようです。赤切符もきられる ようになるとのことで、自転車に酔っ払ってのって自動車の免停なんかになりかね無いので注意です)

15歳は対象なので、高校生の子供がおられる家庭は気をつけた方がよさそうです。知ら無い間に5万の罰金する必要が、、、 なんて事が多発するのでは、、、知らなかったではすまされ無い事になりそう

参考:ルビを振る
参考:「スマホ利用」「イヤホンで音楽」もNG? 今日から道交法の自転車規制が強化
参考:自転車ダイエッターは要注意!6月から規制強化だって

やってみた

さて、まずはそのまま貼り付けてみて。SwiftサラリーマンのSwiftにスウィフトのルビをつけられるかトライしてみます。 UIViewのdrawRectでテキストを描画されています。


import CoreText
import UIKit

class View: UIView {
    override func drawRect(rect: CGRect) {
        let string = "Swift"
        let ruby = "スウィフト"
        
        var text = [.passRetained(ruby) as Unmanaged?, .None, .None, .None]
        let annotation = CTRubyAnnotationCreate(.Auto, .Auto, 0.5, &text)
        
        let attributed = NSAttributedString(string: string, attributes: [
            NSFontAttributeName: UIFont(name: "HiraMinProN-W6", size: 50.0)!,
            NSForegroundColorAttributeName: UIColor(red: 0, green: 0, blue: 0, alpha: 1.0),
            kCTRubyAnnotationAttributeName: annotation.takeUnretainedValue(),
            ])
        
        let size = attributed.boundingRectWithSize(
            CGSizeMake(rect.width, rect.width),
            options: .UsesLineFragmentOrigin,
            context: nil)
        
        let context = UIGraphicsGetCurrentContext()
        
        CGContextSetRGBFillColor(context, 1, 1, 1, 1.0)
        CGContextAddRect(context, rect)
        CGContextFillPath(context)
        
        CGContextTranslateCTM(context, (rect.width - size.width) / 2.0, 200.0)
        CGContextScaleCTM(context, 1.0, -1.0)
        
        let line = CTLineCreateWithAttributedString(attributed)
        CTLineDraw(line, context)
    }
}

class ViewController: UIViewController {
    override func loadView() {
        super.loadView()
        
        self.view = View()
    }
}

で、できました。woxtuさんのコードを参考にさせてもらっています

サンプル画像

このwoxtuさんのサンプルには縦書きのcoretextサンプルもありましたので、それも利用すると以下のように。

サンプル画像

これであれば、、、自転車の「転」だけを横にすることもできそうな気がしてきました。継続してみます


import CoreText
import UIKit

extension String {
    func find(#pattern: String) -> NSTextCheckingResult? {
        let re = NSRegularExpression(pattern: pattern, options: .allZeros, error: nil)!
        return re.firstMatchInString(self, options: nil, range: NSMakeRange(0, count(self.utf16)))
    }
    
    func replace(#pattern: String, template: String) -> String {
        let re = NSRegularExpression(pattern: pattern, options: .allZeros, error: nil)!
        return re.stringByReplacingMatchesInString(
            self,
            options: .ReportProgress,
            range: NSMakeRange(0, count(self.utf16)),
            withTemplate: template);
    }
}

class View: UIView {
    override func drawRect(rect: CGRect) {
        
        let text = "自|転《横変換》車";
        
        let attributed =
        text
            .replace(pattern: "(|.+?《.+?》)", template: ",$1,")
            .componentsSeparatedByString(",")
            .map { x -> NSAttributedString in
                if let pair = x.find(pattern: "|(.+?)《(.+?)》") {
                    let string = (x as NSString).substringWithRange(pair.rangeAtIndex(1))
                    return NSAttributedString(
                        string: string,
                        attributes: [NSVerticalGlyphFormAttributeName: true])
                } else {
                    return NSAttributedString(
                        string: x,
                        attributes: [NSVerticalGlyphFormAttributeName: false])
                }
            }
            .reduce(NSMutableAttributedString()) { $0.appendAttributedString($1); return $0 }
        
        let size = attributed.boundingRectWithSize(
            CGSizeMake(rect.width, rect.width),
            options: .UsesLineFragmentOrigin,
            context: nil)
        
        let context = UIGraphicsGetCurrentContext()
        
        CGContextSetRGBFillColor(context, 1, 1, 1, 1.0)
        CGContextAddRect(context, rect)
        CGContextFillPath(context)
        
        CGContextTranslateCTM(context, (rect.width - size.width) / 2.0, 200.0)
        CGContextScaleCTM(context, 1.0, -1.0)
        
        let line = CTLineCreateWithAttributedString(attributed)
        CTLineDraw(line, context)
    }
}

class ViewController: UIViewController {
    override func loadView() {
        super.loadView()
        
        self.view = View()
    }
}

サンプル画像

それとなくできました。画像小さい、、、、。map関数あたりが正直よくわかっていないので、 不要な部分だらけです..... ただ、だけを横にすることはできました。文字の位置がずれてしまうんですね、、、、 このあたりも調整する必要がありそうです。もっと削ぎ落とす場所が多いので修正していまいります。

追記(上記ソースコードを整理しました)

上記mapの箇所を調整してスッキリしました(2015/6/1 午後)


import CoreText
import UIKit

class View: UIView {
    override func drawRect(rect: CGRect) {
        
        var attributed:NSMutableAttributedString = NSMutableAttributedString();
        attributed.appendAttributedString(NSAttributedString(string:"自",attributes: [NSVerticalGlyphFormAttributeName: false]));
        attributed.appendAttributedString(NSAttributedString(string:"転",attributes: [NSVerticalGlyphFormAttributeName: true]));
        attributed.appendAttributedString(NSAttributedString(string:"車",attributes: [NSVerticalGlyphFormAttributeName: false]));
        
        let size = attributed.boundingRectWithSize(
            CGSizeMake(rect.width, rect.width),
            options: .UsesLineFragmentOrigin,
            context: nil)
        
        let context = UIGraphicsGetCurrentContext()
        
        CGContextSetRGBFillColor(context, 1, 1, 1, 1.0)
        CGContextAddRect(context, rect)
        CGContextFillPath(context)
        
        CGContextTranslateCTM(context, (rect.width - size.width) / 2.0, 200.0)
        CGContextScaleCTM(context, 1.0, -1.0)
        
        let line = CTLineCreateWithAttributedString(attributed)
        CTLineDraw(line, context)
    }
}

class ViewController: UIViewController {
    override func loadView() {
        super.loadView()
        
        self.view = View()
    }
}

まとめ

このソースコードは汚い(私が修正した箇所。オリジナルのコードはとても綺麗です!)ですので、整理していきます!いつも汚いソースコードで失礼しておりますorz

前の記事はこちらです!

次の記事はこちらです!

↓こんな記事もありますよ!

GはGoogle他のアルファベットを勝手に妄想してみる

さて昨日はGoogleが衝撃的な発表でAlphabetという親会社をつくって、Googleはアルファベットの中のGがGoogleとの 位置づけで今後展開していくとの事。ネーミングもですが、今後の期待を大きく感じる、またわかりやすく好印象だったのか株価も 大きく上がったとのことでした。さて、その他残りのアルファベットはどんな風になるのかなぁと勝手に歩きながら妄想してみました。

Rebuildfm(Poadcast)の技術話+オタ話が超絶に面白い、、、、、

去年の暮れ頃から聞いているPodcastを紹介します。IT企業の友人から「RebuldFM」が面白いよ〜と、私が Swiftサラリーマンを始めたことでSwiftの話をしてたら「知ってる知ってる」との話になって、どこで聞いたの? 「Rebuldfm」ってPodcastがあるんだよ、と。

SqliteのDBファイル保存+レビュー却下

2回既にレビューを通過していたアプリが、バイナリレビューで却下されてしまいました。理由は、2.23 Details On launch and content download, your app stores 26.48MB on the user's iCloud, which does not comply with the iOS Data Storage となっていてiCouldに保存される量にしては多いから管理してください、といった旨の内容でした。別に却下理由に難癖つけるつもりではないのですが、最初のレビュー時にいってほしい。。。
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!