web-dev-qa-db-ja.com

iphoneUITextViewは行間隔を設定します

UITextViewの行間を増やしてiPhoneの「メモ」アプリのようにするにはどうすればよいですか?

14
Satyam

さて、iOS6では、NSParagraphStyleを使用する可能性がありますが、文書化が非常に不十分で、ほとんど機能しないようです。

私は現在このように取り組んでいます:

UITextView *lab = [LocalTexts objectAtIndex:j];

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple = 50.0f;
paragraphStyle.maximumLineHeight = 50.0f;
paragraphStyle.minimumLineHeight = 50.0f;

NSString *string = lab.text;
NSDictionary *ats = @{
    NSFontAttributeName: [UIFont fontWithName:@"DIN Medium" size:16.0f],
    NSParagraphStyleAttributeName: paragraphStyle, 
};

lab.attributedText = [[NSAttributedString alloc] initWithString:string attributes:ats];

問題は、フォントを設定すると、行の高さが機能しなくなることです。非常に奇妙な。私はまだそれに対する修正を見つけていません。

また、カスタムのAttributed CoreTextビューを作成することもできます...しかし、もう少し技術的です。その方法のデモを見つけることができます ここ

何かがお役に立てば幸いです。

Swift 4およびiOS11では、必要に応じて、次の3つの実装のいずれかを順番に選択できます。あなたの問題を解決するために。


#1。 StringおよびUIFontDescriptorSymbolicTraitstraitLooseLeadingプロパティの使用

traitLooseLeading には次の宣言があります。

フォントは、より緩い先行値を使用します。

_static var traitLooseLeading: UIFontDescriptorSymbolicTraits { get }
_

次のコードは、traitLooseLeadingをより緩いフォントでリードするために、UItextViewを実装する方法を示しています。

_import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let textView = UITextView()
        view.addSubview(textView)

        textView.text = """
        Lorem ipsum
        Dolor sit amet,
        consectetur adipiscing elit
        """

        if let fontDescriptor = UIFontDescriptor
            .preferredFontDescriptor(withTextStyle: UIFontTextStyle.body)
            .withSymbolicTraits(UIFontDescriptorSymbolicTraits.traitLooseLeading) {
            let looseLeadingFont = UIFont(descriptor: fontDescriptor, size: 0)
            textView.font = looseLeadingFont
        }

        // Layout textView
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor).isActive = true
        textView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor).isActive = true
        textView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor).isActive = true
    }

}
_

#2。 NSAttributedStringおよびNSMutableParagraphStylelineSpacingプロパティの使用

lineSpacing には次の宣言があります。

1つのラインフラグメントの下部と次のラインフラグメントの上部の間のポイント単位の距離。

_var lineSpacing: CGFloat { get set }
_

次のコードは、lineSpacingの一部の属性付きテキストに特定の行間隔を設定するために、UItextViewを実装する方法を示しています。

_import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let string = """
        Lorem ipsum
        Dolor sit amet,
        consectetur adipiscing elit
        """

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 15

        let attributes: [NSAttributedStringKey: Any] = [NSAttributedStringKey.paragraphStyle: paragraphStyle]
        let attributedString = NSAttributedString(string: string, attributes: attributes)

        let textView = UITextView()
        textView.attributedText = attributedString
        view.addSubview(textView)

        // Layout textView
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor).isActive = true
        textView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor).isActive = true
        textView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor).isActive = true
    }

}
_

#3。 StringおよびNSLayoutManagerDelegateプロトコルlayoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)メソッドの使用

layoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:) には次の宣言があります。

指定されたグリフインデックスで終わる行の後の間隔を返します。 [...]このメッセージは、レイアウトマネージャーの委任者が線の形状をカスタマイズできるように、各線がレイアウトされている間に送信されます。

_optional func layoutManager(_ layoutManager: NSLayoutManager, lineSpacingAfterGlyphAt glyphIndex: Int, withProposedLineFragmentRect rect: CGRect) -> CGFloat
_

次のコードは、UItextViewに特定の行間隔を設定するためにlayoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)を実装する方法を示しています。

_import UIKit

class ViewController: UIViewController, NSLayoutManagerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let textView = UITextView()
        textView.layoutManager.delegate = self
        view.addSubview(textView)

        textView.text = """
        Lorem ipsum
        Dolor sit amet,
        consectetur adipiscing elit
        """

        // Layout textView
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor).isActive = true
        textView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor).isActive = true
        textView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor).isActive = true
    }

    // MARK: - NSLayoutManagerDelegate

    func layoutManager(_ layoutManager: NSLayoutManager, lineSpacingAfterGlyphAt glyphIndex: Int, withProposedLineFragmentRect rect: CGRect) -> CGFloat {
        return 15
    }

}
_

前のコードの代わりに、次のコードは、UITextViewサブクラスにlayoutManager(_:lineSpacingAfterGlyphAt:withProposedLineFragmentRect:)を実装する方法を示しています。

_import UIKit

class LineSpacingTextView: UITextView, NSLayoutManagerDelegate {

    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        layoutManager.delegate = self
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - NSLayoutManagerDelegate

    func layoutManager(_ layoutManager: NSLayoutManager, lineSpacingAfterGlyphAt glyphIndex: Int, withProposedLineFragmentRect rect: CGRect) -> CGFloat {
        return 15
    }

}
_
_import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let textView = LineSpacingTextView()
        view.addSubview(textView)

        textView.text = """
        Lorem ipsum
        Dolor sit amet,
        consectetur adipiscing elit
        """

        // Layout textView
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor).isActive = true
        textView.bottomAnchor.constraint(equalTo: view.readableContentGuide.bottomAnchor).isActive = true
        textView.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor).isActive = true
        textView.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor).isActive = true
    }

}
_
15
Imanou Petit

行間隔を変更するには:

NSString *textViewText =self.myTextView.text;

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:textViewText];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = 30;
NSDictionary *dict = @{NSParagraphStyleAttributeName : paragraphStyle };
[attributedString addAttributes:dict range:NSMakeRange(0, [textViewText length])];

self.myTextView.attributedText = attributedString;
11
sash

UITextViewのドキュメントを見るだけで、行間隔の変更がそのコントロールでサポートされていないことを確認できます。

iOS 6以降の場合:

NSParagraphStyleを使用すると、可能性があります。

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple = 50.0f;
paragraphStyle.maximumLineHeight = 50.0f;
paragraphStyle.minimumLineHeight = 50.0f;
NSString *string = @"your paragraph here";
NSDictionary *attribute = @{
   NSParagraphStyleAttributeName : paragraphStyle, 
   };
[textview setFont:[uifont fontwithname:@"Arial" size:20.0f]];
textview.attributedText = [[NSAttributedString alloc] initWithString:string attributes:attribute];
9
KingofBliss

Swift 2.2の場合

let paragraphStyle: NSMutableParagraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 20.0
paragraphStyle.maximumLineHeight = 20.0
paragraphStyle.minimumLineHeight = 20.0
let ats = [NSFontAttributeName: UIFont(name: "Helvetica Neue", size: 11.0)!, NSParagraphStyleAttributeName: paragraphStyle]
cell.textView.attributedText = NSAttributedString(string: "you string here", attributes: ats)
5
swiftBoy

最終結果が行間隔を増やすことである場合は、InterfaceBuilderで直接行うことができます。 Textプロパティを "Attributed"に設定し、右側の...をクリックします。そこでSpacingプロパティを設定すると、行間隔が正しく更新されます。

4
mcfroob

上記のいくつかの回答では、属性lineHeightMultipleが誤用されています。

paragraphStyle.lineHeightMultiple = 50.0f;

公式ドキュメントに従うと、lineHeightMultipleは乗数であり、文字列の絶対的な高さではありません。

レシーバーの自然なラインの高さは、最小および最大のラインの高さによって制約される前に、この係数(正の場合)で乗算されます。このプロパティのデフォルト値は0.0です。 https://developer.Apple.com/library/prerelease/ios/documentation/Cocoa/Reference/ApplicationKit/Classes/NSParagraphStyle_Class/index.html#//Apple_ref/occ/instp/NSParagraphStyle/maximumLineHeight

それにより、以下のコード:

paragraphStyle.lineHeightMultiple = 50.0f;
paragraphStyle.maximumLineHeight = 50.0f;
paragraphStyle.minimumLineHeight = 50.0f;

と同等です

paragraphStyle.lineHeight = 50.0f
1
Yuri Vorontsov
 NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
   paragraphStyle.lineHeightMultiple = 50.0f;
   paragraphStyle.maximumLineHeight = 50.0f;
   paragraphStyle.minimumLineHeight = 50.0f;
     NSString *string = @"if you want reduce or increase space between lines in uitextview ,you can do this with this,but donot set font on this paragraph , set this on uitextveiw.";

    NSDictionary *ats = @{
   NSParagraphStyleAttributeName : paragraphStyle, 
     };

    [textview setFont:[uifont fontwithname:@"Arial" size:20.0f]];
    textview.attributedText = [[NSAttributedString alloc] initWithString:string attributes:ats];
0
kshitij godara