Reputation: 1842
I just created a custom method using a TextKit
stack but am confused by what appears to be a difference between the size of NSTextContainer
and the NSTextView
frame size. The text has a white border and I’d like to know how to get rid of it (see update). The area following the last character is also white. I’ve set an attribute for backgroundColor
using a range that matches the length of the string but so far I have not found a way to apply this attribute to the entire area.
I tried various combinations of settings for NSTextContainer
and the text frame of UITextView
. The following statements get closest to the desired result but the white border is still there.
// A
textContainer = [[NSTextContainer alloc] initWithSize:textFrame.size];
// D
UITextView *textView = [[UITextView alloc] initWithFrame: textFrame textContainer: textContainer];
I worked through tutorials on TextKit
here and here and searched through Apple documentation here here and here. I also checked the closest question and yes, my appDelegate
has
[self.window makeKeyAndVisible];
Update
The white border has been eliminated following the answer here (thanks Larme)
The following statements were added to textView
at the end of the method
textView.textContainerInset = UIEdgeInsetsZero;
textView.textContainer.lineFragmentPadding = 0;
In case it’s relevant, the app was started in iOS 4. It now runs iOS 11 using Xcode Version 9.2. It already uses textView
and TextKit
is now being considered (reluctantly) as a way to address a number of requests from app testers. So any pointer that might help explain and fix this problem would be welcome.
Thanks in anticipation.
Here is the code for the method. helpMessage
is read from an Array (not shown).
-(id)formatHelpText:(NSString*)helpMessage
{
float sideMargin = 5;
float topMargin = 72;
CGFloat textWidth = [UIScreen mainScreen].bounds.size.width - (sideMargin * 2);
CGFloat textHeight = [UIScreen mainScreen].bounds.size.height - (topMargin * 2);
CGRect textFrame = CGRectMake(sideMargin, topMargin, textWidth, textHeight); // used for A & D
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:helpMessage];
// define paragraph attributes
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:1.5];
[style setAlignment:NSTextAlignmentLeft];
// use attributedText to define character attributes
float spacing = 0.0f;
float baselineOffSet = 1.0f;
[attributedText setAttributes:@{
NSFontAttributeName:[UIFont preferredFontForTextStyle:UIFontTextStyleBody],
NSBaselineOffsetAttributeName:[NSNumber numberWithFloat:baselineOffSet],
NSForegroundColorAttributeName:[UIColor whiteColor],
NSBackgroundColorAttributeName:[UIColor grayColor],
NSParagraphStyleAttributeName:style,
NSKernAttributeName:@(spacing)
}
range:range];
// TextKit - non-view
NSTextStorage *textStorage;
NSLayoutManager *layoutManager;
NSTextContainer *textContainer;
textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedText];
layoutManager = [[NSLayoutManager alloc] init];
textContainer = [[NSTextContainer alloc] init];
[textStorage addLayoutManager:layoutManager];
// A
textContainer = [[NSTextContainer alloc] initWithSize:textFrame.size];
// B
// textContainer = [[NSTextContainer alloc] initWithSize:[UIScreen mainScreen].bounds.size];
[layoutManager addTextContainer:textContainer];
// C
// UITextView *textView = [[UITextView alloc] initWithFrame: [UIScreen mainScreen].bounds textContainer: textContainer];
// D
UITextView *textView = [[UITextView alloc] initWithFrame: textFrame textContainer: textContainer];
// update
textView.textContainerInset = UIEdgeInsetsZero;
textView.textContainer.lineFragmentPadding = 0;
return textView;
}
Upvotes: 1
Views: 1624
Reputation: 1842
Both problems are now solved. The white border was removed using UIEdgeInsetsZero
to clear the default setting and textContainer.lineFragmentPadding = 0
(thanks, Larme). I hid the unhighlighted part of the last line of UITextView
by removing background colour as a character attribute and defining it instead as a property of textView.
sizeToFit
is added to minimise the number of lines in textView
. Here is the final code
#import "HelpTextView.h"
@implementation HelpTextView
-(id)formatHelpText:(NSString*)helpMessage
{
float sideMargin = 5;
float topMargin = 72;
CGFloat textWidth = [UIScreen mainScreen].bounds.size.width - (sideMargin * 2);
CGFloat textHeight = [UIScreen mainScreen].bounds.size.height - (topMargin * 2);
CGRect textFrame = CGRectMake(sideMargin, topMargin, textWidth, textHeight);
NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:helpMessage];
// define paragraph attributes
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:0.5];
[style setAlignment:NSTextAlignmentLeft];
float spacing = 0.0f;
float baselineOffSet = 1.0f;
NSRange range = (NSRange){0,[attributedText length]};
// use attributedText to define character attributes
[attributedText setAttributes:@{
NSFontAttributeName:[UIFont preferredFontForTextStyle:UIFontTextStyleBody],
NSBaselineOffsetAttributeName:[NSNumber numberWithFloat:baselineOffSet],
NSForegroundColorAttributeName:[UIColor whiteColor],
NSParagraphStyleAttributeName:style,
NSKernAttributeName:@(spacing)
}
range:range];
NSTextStorage* textStorage = [[NSTextStorage alloc] initWithAttributedString:attributedText];
NSLayoutManager *layoutManager = [NSLayoutManager new];
[textStorage addLayoutManager:layoutManager];
CGSize containerSize = CGSizeMake(textFrame.size.width, CGFLOAT_MAX);
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:containerSize];
[layoutManager addTextContainer:textContainer];
UITextView *textView = [[UITextView alloc] initWithFrame: textFrame textContainer: textContainer];
textView.textContainerInset = UIEdgeInsetsZero;
textView.textContainer.lineFragmentPadding = 0;
textView.editable = NO;
textView.scrollEnabled = NO;
textView.backgroundColor = [UIColor grayColor];
[textView sizeToFit];
return textView;
}
Upvotes: 0