繁体   English   中英

UITextView exclusionPaths右下角

[英]UITextView exclusionPaths bottom right

我正在尝试为邮件做whatsapp之类的消息,因为它具有一个根据contentsize调整大小并在右下角具有日期的单元格...问题是我不知道排除路径的矩形位置,因为文本是动态的,我有类似的内容,但仅适用于多行,但不适用于单行:

whatsapp消息窗口

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));

我的同事在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)
        }
    }

我遇到了同样的问题( 对我来说,这是一个在右上角的按钮 ),并且有解决方法:

- (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 ];
}

我也有同样的问题。 我添加了具有属性的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;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM