ibireme / YYText

Powerful text framework for iOS to display and edit rich text.
MIT License
8.86k stars 1.7k forks source link

为何YYTextView 的 YYTextAttachment 图片会遮挡文字呢? #118

Closed fcgeek closed 8 years ago

fcgeek commented 8 years ago

为何YYTextView 的 YYTextAttachment 图片会遮挡文字...

UITextView 效果 image

YYTextView 效果 image

    var text:NSMutableAttributedString!
    if textView.attributedText == nil {
        text = NSMutableAttributedString()
    } else {
        text = NSMutableAttributedString(attributedString: textView.attributedText)
    }

    // Heiti SC 字体。。
    let ascent = parser.picFont.pointSize * 0.86;
    let descent = parser.picFont.pointSize * 0.14;
    let bounding = CGRectMake(0, -0.14 * parser.picFont.pointSize, parser.picFont.pointSize, parser.picFont.pointSize);
    let delegate = YYTextRunDelegate()
    delegate.ascent = ascent
    delegate.descent = descent
    delegate.width = bounding.size.width

    let textAttachment = YYTextAttachment()
    textAttachment.contentMode = .ScaleAspectFit
    textAttachment.contentInsets = UIEdgeInsetsMake(ascent - (bounding.size.height + bounding.origin.y), 0, -descent - bounding.origin.y, 0);
    textAttachment.content = image
    let atr = NSMutableAttributedString(string: YYTextAttachmentToken)
    atr.setTextAttachment(textAttachment, range: NSMakeRange(0, atr.length))
    let ctDelegate = delegate.CTRunDelegate()
    atr.setRunDelegate(ctDelegate, range: NSMakeRange(0, atr.length))
    text.insertAttributedString(atr, atIndex: selectedRange.location)
    text.appendAttributedString(atr)
    textView.attributedText = text
ibireme commented 8 years ago

你可以试试直接用这三个已经封装好的方法:https://github.com/ibireme/YYText/blob/master/YYText/Utility/NSAttributedString%2BYYText.m#L552-L673 ,或者仿照这几个方法来自己创建 Attachment。

也可以试试开启调试模式,看一下具体的排版结果:

YYTextDebugOption *debugOptions = [YYTextDebugOption new];
debugOptions.baselineColor = [UIColor redColor];
debugOptions.CTFrameBorderColor = [UIColor redColor];
debugOptions.CTLineFillColor = [UIColor colorWithRed:0.000 green:0.463 blue:1.000 alpha:0.180];
debugOptions.CGGlyphBorderColor = [UIColor colorWithRed:1.000 green:0.524 blue:0.000 alpha:0.200];
[YYTextDebugOption setSharedDebugOption:debugOptions];
fcgeek commented 8 years ago

@ibireme 非常感谢你的回答。我用了你封装好的方法,并且调试模式也打开了。 使用Top | Center时,图片后面的字符串换行会被遮挡,使用Bottom 时图片前面的字符串会被遮挡。 似乎是因为图片占位只有一行的原因,如何让它的占位和它的大小一致呢?

Top image

Center image

Bottom image

    text.appendAttributedString(NSAttributedString.attachmentStringWithContent(image, contentMode: .Center, attachmentSize: image.size, alignToFont: parser.defualtFont, alignment: .Center))
    textView.attributedText = text
ibireme commented 8 years ago

这。。是不是设置了什么 linePositionModifier 之类的东西,把行文本行固定了?

fcgeek commented 8 years ago

找到原因了,YQTextLinePositionModifier 限制了行高。 非常感谢你回答。

fcgeek commented 8 years ago

但有个新问题,换了一行的时候,空白了一大段。 image

ibireme commented 8 years ago

这个。。这是怎么用的啊。。能贴一下具体的使用代码吗?

fcgeek commented 8 years ago
    textView = YYTextView()
    textView.textContainerInset = UIEdgeInsetsMake(12, 16, 12, 16)
    textView.contentInset = UIEdgeInsetsMake(0, 0, YQComposeToolbar.toolBarHeight, 0)
    textView.extraAccessoryViewHeight = YQComposeToolbar.toolBarHeight
    textView.showsVerticalScrollIndicator = false
    textView.alwaysBounceVertical = true
    textView.allowsCopyAttributedString = false
    textView.textParser = parser
    textView.delegate = self
    textView.inputAccessoryView = UIView()

    textView.placeholderText = "写点什么吧..."
    textView.placeholderTextColor = UIColor.lightGrayColor()
    textView.placeholderFont = UIFont.systemFontOfSize(14)

    var text:NSMutableAttributedString!
    if textView.attributedText == nil {
        text = NSMutableAttributedString()
    } else {
        text = NSMutableAttributedString(attributedString: textView.attributedText)
    }
 let image = UIImage(named:"")
  image = image.resizedImageByWidth(UInt(self.width-32))
    let attachmentString = NSAttributedString.attachmentStringWithContent(image, contentMode: .Center, attachmentSize: image.size, alignToFont: parser.defualtFont, alignment: .Center)
    text.insertAttributedString(attachmentString, atIndex: selectedRange.location)
    text.insertAttributedString(NSAttributedString(string: "\n"), atIndex: selectedRange.location + attachmentString.length)
    selectedRange.location = selectedRange.location + attachmentString.length + 1
    textView.attributedText = text
ibireme commented 8 years ago

暂时没看出什么问题。。猜测有下面几种可能:

  1. attachment 里会用 RunDelegate 来重新设置文字的 ascent、descent,这个可能会被错误的扩散到别的字符上。这可以在设置 attributedText、并经过 parser 解析后,打印下实际显示的 attributedText 来看看是否有错误。
  2. 看看是否有修改 font、line space 等属性,这个也可以按上面这样打印来看看。
  3. attachment 宽度应该小于文本控件的宽度,不然在某些情况下会导致 CoreText 排版结果有问题。
fcgeek commented 8 years ago

@ibireme 谢谢了,是我在TextParser 设置了字体的原因。