我正在尝试做一些类似于消息的消息,因为有一个基于内容大小调整大小的单元格,并在右下角有日期...问题是我不知道矩形位置排除的路径,因为文本是动态的,我有这样的东西,但只适用于多行,但不适用于单行:
NSString *txt=@"I'm writing ";//a text renderer using Core Text, and I discovered I’ll need to wrap text around objects (such as is done in any DTP program). I couldn’t find any easy answers as to how to do this in the documentation, so having finally got it working I’ll share what I did. To lay out text in a custom shape in Core Text, you can pass a CGPath in when you create your CTFramesetterRef. Originally this only supported rectangular paths, but now it supports fully custom paths. My first thought was to see if I could subtract the region to wrap around from the path for my frame’s border, and pass the result in to Core Text as a path. It turns out firstly that subtracting one path from another in Core Graphics is not trivial. However, if you simply add two shapes to the same path, Core Graphics can use a winding rule to work out which areas to draw. Core Text, at least as of iOS 4.2, can also use this kind of algorithm. This will work for many cases: if you can guarantee that your object to be wrapped will be fully inside the frame (and not overlapping the edge), just go ahead and add its border to the same path as your frame, and Core"; // Text will do the rest.";
txtText.text=txt;
CGSize textFrame = [txtText sizeThatFits:CGSizeMake(235, MAXFLOAT)];
UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(textFrame.width-35, textFrame.height-20, 35, 20)];
txtText.textContainer.exclusionPaths = @[imgRect];
textFrame = [txtText sizeThatFits:CGSizeMake(235, MAXFLOAT)];
//int frameWidth=375;
txtText.frame=CGRectIntegral(CGRectMake(10, 10, textFrame.width, textFrame.height));
lblHour.frame=CGRectIntegral(CGRectMake(textFrame.width-35, textFrame.height-15, 35, 20));
viewCanvasAround.frame=CGRectIntegral(CGRectMake(50, 100, textFrame.width+20, textFrame.height+20));
答案 0 :(得分:0)
我的同事在actor.im中找到了一个很好的解决方案。 https://github.com/actorapp/actor-platform/blob/master/actor-sdk/sdk-core-ios/ActorSDK/Sources/Controllers/Content/Conversation/Cell/AABubbleTextCell.swift#L312
let container = YYTextContainer(size: CGSizeMake(maxTextWidth, CGFloat.max))
textLayout = YYTextLayout(container: container, text: attributedText)!
// print("Text Layouted")
// Measuring text and padded text heights
let textSize = textLayout.textBoundingSize
if textLayout.lines.count == 1 {
if textLayout.textBoundingSize.width < maxTextWidth - timeWidth {
//
// <line_0> <date>
//
bubbleSize = CGSize(width: textSize.width + timeWidth, height: textSize.height)
} else {
//
// <line_________0>
// <date>
//
bubbleSize = CGSize(width: textSize.width, height: textSize.height + 16)
}
} else {
let maxWidth = textSize.width
let lastLine = textLayout.lines.last!.width
if lastLine + timeWidth < maxWidth {
//
// <line_________0>
// <line_________1>
// ..
// <line_n> <date>
//
bubbleSize = textSize
} else if lastLine + timeWidth < maxTextWidth {
//
// |------------------|
// <line______0>
// <line______1>
// ..
// <line______n> <date>
//
bubbleSize = CGSize(width: max(lastLine + timeWidth, maxWidth), height: textSize.height)
} else {
//
// <line_________0>
// <line_________1>
// ..
// <line_________n>
// <date>
//
bubbleSize = CGSize(width: max(timeWidth, maxWidth), height: textSize.height + 16)
}
}
答案 1 :(得分:0)
我遇到了同样的问题(对我来说这是一个右下角的按钮)并且我有办法解决它:
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self updateTextExclusionPaths];
}
- (void)updateTextExclusionPaths {
// Remove old exclusionPaths to calculate right rects of new
textView.textContainer.exclusionPaths = @[];
// Force textView to layout the text without exclusionPaths
[textView.layoutManager glyphRangeForTextContainer:textView.textContainer];
/// Because of some specifics of my implementation I had a problem with wrong frame of my button. So I calculated it manually
// Calculate new exclusionPaths
CGRect buttonFrameInTextView = [superViewOfTextView convertRect:button.frame toView:textView];
// Calculate textView.text size without any exclusionPaths to calculate right button frame
CGSize textViewSize = [textView sizeThatFits:CGSizeMake(textView.frame.size.width, CGFLOAT_MAX)];
// Update Y position of button
buttonFrameInTextView.origin.y = size.height - buttonFrameInTextView.size.height;
// Add new exclusionPaths
UIBezierPath *buttonRectBezierPath = [UIBezierPath bezierPathWithRect:buttonFrameInTextView];
textView.textContainer.exclusionPaths = @[ buttonRectBezierPath ];
}
答案 2 :(得分:0)
我也有同样的问题。我添加了具有属性的textAttachment属性化字符串。您将设置一个估计的最大大小。单行也没有问题。 (对不起,我的英语不好。)
这是示例代码。
var text: String! {
didSet {
let font = UIFont.systemFont(ofSize: 13);
let att = NSMutableAttributedString.init(string: text, attributes: [NSAttributedString.Key.foregroundColor : UIColor.black,
NSAttributedString.Key.font : font]);
let attachment = NSTextAttachment.init(data: nil, ofType: nil);
var size = extraSize;
size.height = font.lineHeight;
attachment.bounds = CGRect.init(origin: CGPoint.init(), size: size);
att.append(NSAttributedString.init(attachment: attachment));
textView.attributedText = att;
}
}