String yang diatribusikan dengan font khusus di storyboard tidak dimuat dengan benar

100

Kami menggunakan font khusus dalam proyek kami. Ia bekerja dengan baik di Xcode 5. Dalam Xcode 6, ia bekerja dalam teks biasa, yang dikaitkan dengan string dalam kode. Tetapi string yang dikaitkan di storyboard semuanya kembali ke Helvetica saat berjalan di simulator atau perangkat, meskipun semuanya terlihat baik-baik saja di storyboard.

Saya tidak yakin apakah itu bug dari Xcode 6 atau iOS 8 SDK, atau cara menggunakan font khusus diubah di Xcode 6 / iOS 8?

Allen Hsu
sumber
Masalah yang sama disini. Ingin tahu apa yang terjadi.
obeattie
1
Untuk saat ini, kami membuat UILabel khusus, bernama GLMarkdownLabel, dan mengekspor beberapa properti dengan IBInspectable, lalu menyetel string penurunan harga di storyboard, dan menerjemahkan string penurunan harga kembali ke string yang diatribusikan saat bangun dari nib.
Allen Hsu
Sekarang solusi jangka panjang, semoga Apple akan memperbaiki bug ini di versi Xcode berikutnya.
Allen Hsu
Astaga, cruft seperti itu. Terima kasih telah memberi tahu kami bahwa ini bukan masalah yang terisolasi. Apakah ada radar?
obeattie
1
Solusi kami pada akhirnya adalah kembali menggunakan IBCustomFonts untuk label terkait kami.
yonix

Jawaban:

30

Perbaikan bagi saya adalah menggunakan IBDesignablekelas:

import UIKit

@IBDesignable class TIFAttributedLabel: UILabel {

    @IBInspectable var fontSize: CGFloat = 13.0

    @IBInspectable var fontFamily: String = "DIN Light"

    override func awakeFromNib() {
        var attrString = NSMutableAttributedString(attributedString: self.attributedText)
        attrString.addAttribute(NSFontAttributeName, value: UIFont(name: self.fontFamily, size: self.fontSize)!, range: NSMakeRange(0, attrString.length))
        self.attributedText = attrString
    }
}

Memberi Anda ini di Interface Builder:

Font kustom Interface Builder dengan string yang diatribusikan

Anda dapat mengatur atributedstring seperti biasa, tetapi Anda harus mengatur ukuran font dan fontfamily sekali lagi di properti baru yang tersedia.

Karena Interface Builder bekerja dengan font khusus secara default, ini menghasilkan apa yang Anda lihat adalah apa yang Anda dapatkan , yang saya lebih suka saat membangun aplikasi.

Catatan

Alasan saya menggunakan ini daripada hanya versi biasa adalah karena saya menyetel properti pada label yang diatribusikan seperti spasi, yang tidak tersedia saat menggunakan gaya biasa.

Antoine
sumber
1
Solusi Anda hanya mendukung satu jenis dan ukuran font untuk sebuah label, lalu mengapa tidak menggunakan teks biasa saja?
Allen Hsu
Demikian pula, kami menggunakan @IBInspectableatribut untuk sementara, bukan font dan ukuran. Kami memiliki markdownTextproperti, karena sebagian besar waktu, kami menggunakan string yang dikaitkan untuk teks tebal atau bergaris bawah. Kemudian parsing teks penurunan harga menjadi string yang dikaitkan dengan font dan ukuran info yang disetel untuk teks biasa.
Allen Hsu
@AllenH, kamu benar. Tidak menyebutkan itu, tapi saya menggunakan spasi baris yang dikaitkan untuk label saya. Offcourse, kalau tidak Anda hanya akan menggunakan gaya polos :)
Antoine
poin bagus, kami mengekspor lineSpacing juga: p Saya rasa saya akan menerima jawaban Anda karena sebenarnya ini adalah bug di Xcode, dan tidak ada solusi yang lebih baik untuk saat ini. Mari kita tunggu versi Xcode selanjutnya.
Allen Hsu
2
Ini tidak akan berhasil jika saya ingin
menebalkan
28

Jawaban paling sederhana yang berhasil adalah menyeret font ke FontBook. Jika font ada di proyek Anda tetapi tidak ada di FontBook komputer Anda, IB terkadang kesulitan menemukannya. Aneh, tetapi telah berhasil untuk saya dalam beberapa kesempatan.

Alan Scarpa
sumber
17
Meskipun ini akan membiarkan Xcode memilih font khusus, itu tidak benar-benar berfungsi. Saat runtime font tidak akan digunakan seperti yang Anda harapkan.
Daniel
Sayangnya saya tidak dapat menemukan solusi. Hal terbaik yang dapat saya lakukan adalah mencatat bug dengan Apple.
Daniel
Ya, inilah cara mengatasinya. Papan cerita saya dirancang oleh pengembang lain, pembaruan svn ok, tetapi tidak pernah mendapatkan font di UI. Font tersebut ada di resource tetapi tidak ditampilkan di UI perangkat / simulator. Karena dia menggunakan string yang diatribusikan, saya harus memilikinya di Font Book. Itu memecahkan masalah.
karim
Iya. ini membantu saya untuk memecahkan masalah yang sama. Ketika saya menambahkan font khusus ke dalam buku font, hal-hal berfungsi seperti pesona.
Sushant Jagtap
1
Meskipun solusi ini berfungsi pada beberapa kasus, saya juga menghadapi masalah yang sama dengan @Daniel dalam proyek yang sama dengan jenis font yang sama. XCode perlu menyelesaikan masalah ini.
dey.shin
16

Anda dapat menambahkan font khusus ke buku font.

Langkah 1 : Klik kelola font. Ini membuka buku font.

masukkan deskripsi gambar di sini

Langkah2 : Klik plus dan tambahkan font Anda.

masukkan deskripsi gambar di sini

Lain kali ketika Anda mengklik font dengan teks yang diatribusikan, font yang baru ditambahkan juga akan ditampilkan dalam daftar. Tetapi pastikan font khusus Anda ditambahkan di info.plist dan sumber daya paket.

mahbaleshwar hegde
sumber
Ini berfungsi di storyboard tetapi setelah menjalankannya tidak menunjukkan pemformatannya
Van
1
@Van format? Bisakah Anda ceritakan lebih banyak? Saat tidak berfungsi?
mahbaleshwar hegde
Saya harus mengatur teks yang cocok dengan rgualr dan huruf tebal. Saya menggunakan solusi di atas, jadi ini berfungsi di storyboard tetapi ketika saya menjalankan aplikasi, label tidak menampilkan font yang diterapkan, melainkan menampilkan font sistem
Van
Apakah Anda menambahkan font kustom Anda di info.plist? Setelah itu baru saja mencetak semua font family
mahbaleshwar hegde
2
Iya. Saya dapat mengatur font khusus di seluruh aplikasi dalam kasus teks biasa, saya perlu mengatur untuk teks yang diatribusikan
Van
5

Berkat utas ini, saya sampai pada solusi ini:

private let fontMapping = [
    "HelveticaNeue-Medium": "ITCAvantGardePro-Md",
    "HelveticaNeue": "ITCAvantGardePro-Bk",
    "HelveticaNeue-Bold": "ITCAvantGardePro-Demi",
]

func switchFontFamily(string: NSAttributedString) -> NSAttributedString {
    var result = NSMutableAttributedString(attributedString: string)
    string.enumerateAttribute(NSFontAttributeName, inRange: NSRange(location: 0, length: string.length), options: nil) { (font, range, _) in
        if let font = font as? UIFont {
            result.removeAttribute(NSFontAttributeName, range: range)
            result.addAttribute(NSFontAttributeName, value: UIFont(name: fontMapping[font.fontName]!, size: font.pointSize)!, range: range)
        }
    }
    return result
}
rexsheng
sumber
1
Ide bagus. Sungguh luar biasa ini rusak di Apple. Mengherankan.
Fattie
4

Solusi saya adalah sedikit solusi. Solusi sebenarnya adalah apel memperbaiki Interface Builder.

Dengan itu Anda dapat menandai semua teks tebal dan miring di pembuat antarmuka menggunakan font sistem, kemudian pada waktu proses merender font kustom Anda. Mungkin tidak optimal di semua kasus.

 NSMutableAttributedString* ApplyCustomFont(NSAttributedString *attributedText,
                     UIFont* boldFont,
                     UIFont* italicFont,
                     UIFont* boldItalicFont,
                     UIFont* regularFont)
{

    NSMutableAttributedString *attrib = [[NSMutableAttributedString alloc] initWithAttributedString:attributedText];
    [attrib beginEditing];
    [attrib enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, attrib.length) options:0
                    usingBlock:^(id value, NSRange range, BOOL *stop)
    {
        if (value)
        {
            UIFont *oldFont = (UIFont *)value;
            NSLog(@"%@",oldFont.fontName);

            [attrib removeAttribute:NSFontAttributeName range:range];

            if([oldFont.fontName rangeOfString:@"BoldItalic"].location != NSNotFound && boldItalicFont != nil)
                [attrib addAttribute:NSFontAttributeName value:boldItalicFont range:range];
            else if([oldFont.fontName rangeOfString:@"Italic"].location != NSNotFound && italicFont != nil)
                [attrib addAttribute:NSFontAttributeName value:italicFont range:range];
            else if([oldFont.fontName rangeOfString:@"Bold"].location != NSNotFound && boldFont != nil)
                [attrib addAttribute:NSFontAttributeName value:boldFont range:range];
            else if(regularFont != nil)
                [attrib addAttribute:NSFontAttributeName value:regularFont range:range];
        }
    }];
    [attrib endEditing];

    return attrib;
}

Terinspirasi dari postingan ini

KidA
sumber
4

Saya telah berjuang dengan bug ini: UILabel ditampilkan dengan benar di IB dengan font khusus tetapi tidak ditampilkan dengan benar di perangkat atau simulator (font disertakan dalam proyek dan digunakan dalam UILabel biasa).

Akhirnya ditemukan Attributed String Creator di (Mac) App Store. Menghasilkan kode untuk ditempatkan di aplikasi Anda di tempat yang sesuai. Fantastis. Saya bukan pencipta, hanya pengguna yang bahagia.

ghr
sumber
3

Memenuhi masalah yang sama: font atribut yang disetel untuk TextView di storyboard tidak berfungsi dalam waktu proses dengan XCode 6.1 & iOS 8 SDK.

Beginilah cara saya memecahkan masalah ini, mungkin bisa menjadi solusi untuk Anda:

  1. buka pemeriksa atribut textview Anda, ubah teks menjadi "Biasa"

  2. klik di salib untuk menghapus "wC hR" (merah di bawah)

    masukkan deskripsi gambar di sini

  3. ubah teks menjadi "Diatributkan", lalu Anda dapat menyetel font dan ukuran teks Anda.

  4. jalankan untuk memeriksa apakah berhasil
Zhihao Yang
sumber
Tampaknya secara default tidak ada wC hRset properti, tidak UILabeljuga UITextView.
Allen Hsu
oleh xcode 6, apakah Anda menyetel tinggi-lebar jenis lain, seperti "Lebar Reguler | Tinggi Apa Pun", "Lebar Ringkas | Tinggi Reguler"? karena saya memiliki proyek yang dikembangkan di Xcode 5 dan textview yang dikaitkan berfungsi bahkan dengan iOS 8 SDK, saya memeriksa pengaturan di sana dan menemukan satu-satunya perbedaan adalah Xcode 6 memungkinkan pengguna untuk mengatur font untuk berbagai ukuran perangkat jika Anda mengatur teks di "Polos". Konfigurasi baru ini mungkin menjadi alasan mengapa menyetel teks di "dikaitkan" tetapi font tidak berfungsi.
Zhihao Yang
1
apakah Anda menggunakan font khusus? Maksud saya yang tertanam sendiri, bukan font sistem.
Allen Hsu
Aha, saya pikir font "Custom" yang Anda sebutkan adalah yang ditawarkan oleh Xcode asalkan memiliki font "System".
Zhihao Yang
Itu tidak berhasil untuk saya. Ini berfungsi untuk string normal tetapi tidak untuk string yang diatribusikan.
Pratik Somaiya
2

Memenuhi masalah yang sama: font atribut untuk UILabel di storyboard tidak berfungsi dalam waktu proses. Menggunakan UIFont + IBCustomFonts.m ini berfungsi untuk saya https://github.com/deni2s/IBCustomFonts

Praveen Sevta
sumber
2

Coba ini akan berhasil

Dalam kasus saya ketika saya mencoba untuk mengatur "Teknologi Silversky" sebagai teks yang diatribusikan untuk label dari pembuat antarmuka itu tidak muncul ketika saya menjalankan simulator tetapi ditampilkan di pembuat antarmuka. Jadi saya menggunakan satu trik saya membuat font Silversky dengan 1 piksel lebih besar dari teks Teknologi.

Teks atribut memiliki masalah dengan ukuran font yang sama jadi ubah ukuran 1 kata hal ini bekerja dengan saya.

Mungkin ini adalah bug xcode tetapi trik ini berhasil untuk saya.

Teknologi Silversky
sumber
1

Masalah yang sama.

Dipecahkan: Cukup centang Selectable di TextView. Tanpa ini saya memiliki font Sistem standar.

Maselko
sumber
1

Klik dua kali dan instal font ke sistem. Ini akan bekerja (Xcode 8.2)

Ishara Meegahawala
sumber
1
Saya berharap itu akan terjadi. Itu tidak bekerja untuk saya dengan FontAwesome.
Peter DeWeese
1

Solusi @Hamidptb berfungsi, pastikan untuk mendapatkan nama font yang benar (setelah Anda menambahkannya ke Buku Font)

  • Buka aplikasi Buku Font, navigasikan ke font Anda lalu tekan Command + I. Nama PostScript adalah nama font yang ingin Anda gunakan di sini:

    UILabel.appearance (). Font = UIFont (nama: " PostScriptName ", ukuran: 17)

itsmcgh
sumber
0

Saya mencoba mendapatkan sel tableView dengan teks yang memiliki banyak paragraf. String yang diatribusikan tampaknya menjadi cara untuk mendapatkan spasi ekstra di antara paragraf (sesuatu yang terlihat sedikit lebih bagus daripada melakukan dua baris-feed dalam string). Menemukan ini dan posting lainnya ketika saya menemukan bahwa pengaturan IB tidak berlaku pada waktu proses ketika Anda ingin meletakkan teks yang berbeda di sel.

Hal utama yang saya temukan adalah menambahkan ekstensi ke String (menggunakan Swift) untuk membuat string yang dikaitkan dengan karakteristik tertentu. Contoh di sini menggunakan font Marker Felt, karena mudah dibedakan dari Helvetica. Contoh ini juga menunjukkan sedikit spasi ekstra di antara paragraf agar lebih berbeda satu sama lain.

extension String {
func toMarkerFelt() -> NSAttributedString {
    var style = NSMutableParagraphStyle()
    style.paragraphSpacing = 5.0
    let markerFontAttributes : [NSObject : AnyObject]? = [
        NSFontAttributeName : UIFont(name: "Marker Felt", size: 14.0)!,
        NSParagraphStyleAttributeName: style,
        NSForegroundColorAttributeName : UIColor.blackColor()
    ]
    let s = NSAttributedString(string: self, attributes: markerFontAttributes)
    return s
    }
}

Kemudian, di tableViewCell kustom saya, Anda mengirimkannya teks yang Anda inginkan dan mengubahnya menjadi string yang diatribusikan pada UILabel.

//  MarkerFeltCell.swift
class MarkerFeltCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
func configureCellWithString(inputString : String) {
    myLabel.attributedText = inputString.toMarkerFelt()
}}

Dalam pengontrol tampilan dengan tableView, Anda harus mendaftarkan sel Anda di viewDidLoad () - Saya menggunakan ujung pena, jadi seperti ini:

let cellName = "MarkerFeltCell"
tableView.registerNib(UINib(nibName: cellName, bundle: nil), forCellReuseIdentifier: cellName)

Untuk mendapatkan sel untuk mengetahui seberapa tinggi seharusnya, buat sel prototipe yang digunakan untuk mendapatkan info ukuran, dan tidak pernah ditambahkan ke tableView. Jadi, dalam variabel pengontrol tampilan Anda:

var prototypeSummaryCell : MarkerFeltCell? = nil

Kemudian di (mungkin menimpa - bergantung pada pengontrol tampilan Anda) heightForRowAtIndexPath:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        // ...
    if xib == "MarkerFeltCell" {
            if prototypeCell == nil {
                prototypeCell = tableView.dequeueReusableCellWithIdentifier(xib) as? MarkerFeltCell
            }
            let width : CGFloat = tableView.bounds.width
            let height : CGFloat = prototypeCell!.bounds.height
            prototypeCell?.bounds = CGRect(x: 0, y: 0, width: width, height: height)
            configureCell(prototypeCell!, atIndexPath: indexPath)
            prototypeSummaryCell?.layoutIfNeeded()
            let size = prototypeSummaryCell!.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
            let nextHeight : CGFloat = ceil(size.height + 1.0)
            return nextHeight
    } else {  // ...

Pada kode di atas, prototypeCell akan diisi saat pertama kali dibutuhkan. PrototypeCell kemudian digunakan untuk mengetahui ketinggian sel setelah melalui proses autosizing. Anda perlu membulatkan ketinggian dengan fungsi ceil (). Saya juga menambahkan beberapa faktor fudge ekstra.

Bit kode terakhir adalah bagaimana Anda mengonfigurasi teks untuk sel. Untuk contoh ini, cukup:

func configureCell(cell :UITableViewCell, atIndexPath indexPath: NSIndexPath) {
    if let realCell = cell as? MarkerFeltCell  {
        realCell.configureCellWithString("Multi-line string.\nLine 2.\nLine 3.")    // Use \n to separate lines
    }
}

Juga, ini bidikan ujung pena. Menyematkan label ke tepi sel (dengan margin yang diinginkan), tetapi menggunakan batasan "Lebih Besar Dari atau Sama dengan", dengan prioritas kurang dari "Wajib" untuk batasan bawah.

Batasan sel

Setel font label ke Dikaitkan. Font IB sebenarnya tidak masalah.

LabelFont

Hasil dalam kasus ini:

CellResults

anorskdev
sumber
0

Dalam hal string yang dikaitkan Anda dapat menambahkan font khusus dalam daftar font sebagai - Klik ikon font ini akan menampilkan dialog berikut. Dalam dialog berikut Anda dapat menambahkan kategori Anda sendiri atau yang sudah ada untuk font kustom. dialog font yang dikaitkan

Setelah itu klik Kelola Font, itu membuka kategori pilih dialog berikut di Anda buat atau yang sudah ada. Klik tanda + untuk menambahkan font dalam kategori. Kelola dialog font

Sunil Singh
sumber
0

itu memiliki penyelesaian yang sederhana dan cepat dan itu berhasil dalam kasus saya. solusi itu adalah menambahkan baris kode di didFinishLaunchingWithOptions func di file AppDelegate.swift:

untuk textView :

UITextView.appearance().font = UIFont(name: "IranSans", size: 17)

untuk label :

UILabel.appearance().font = UIFont(name: "IranSans", size: 17)

dan untuk UiView lainnya seperti ini ☝️

Hamid Reza Ansari
sumber
0

Untuk siapa pun yang menerapkan font khusus ke string yang diatribusikan dalam kode: Coba setel di viewDidLayoutSubviews. Kesalahan saya melakukannya viewDidLoad, tidak akan diterapkan di sana.

sergey.syrotynin
sumber