UITextViewの行間を増やしてiPhoneの「メモ」アプリのようにするにはどうすればよいですか?
さて、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つの実装のいずれかを順番に選択できます。あなたの問題を解決するために。
String
およびUIFontDescriptorSymbolicTraits
traitLooseLeading
プロパティの使用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
}
}
_
NSAttributedString
およびNSMutableParagraphStyle
lineSpacing
プロパティの使用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
}
}
_
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
}
}
_
行間隔を変更するには:
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;
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];
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)
最終結果が行間隔を増やすことである場合は、InterfaceBuilderで直接行うことができます。 Textプロパティを "Attributed"に設定し、右側の...をクリックします。そこでSpacingプロパティを設定すると、行間隔が正しく更新されます。
上記のいくつかの回答では、属性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
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];