Why aren't the backgrounds within these UITextViews clear?

大城市里の小女人 提交于 2019-12-13 03:44:01

问题


I am attempting to display individual characters in the exact positions that they would appear if displayed as a single string with kerning. The problem is that the characters' bounding boxes seem to be opaque, so that each newly added character covers some of the prior one. Where kerning is greater (e.g., in the combination "ToT"), the problem is obvious:

My setup is something like this: I have an SKView embedded in a container view. In an extension of the SKView's view controller, the following are set within a function in this order:

skView.allowsTransparency = true
scene.backgroundColor = .clear

charAttr – [NSAttributedStringKey.backgroundColor: UIColor.clear]

textView.isOpaque = false
textView.backgroundColor = UIColor.clear

Each UITextView is added successively as a subview to the view (which is an SKView).

I've looked all over my code for some clue as to what could be making the character's bounding boxes seem opaque, but I haven't found anything. The sad thing is that I solved this problem sometime last year, but don't remember what I did and don't have the code anymore.

Any insights or ideas would be appreciated.


回答1:


After achieving the sought-after effect in a playground, I pasted this simple code into the extension where the original code was. It still worked, so I made it as close to identical to the original as possible, until it also exhibited the problem.

The SKView and extension aspects were irrelevant. The problem lies with how UITextView frames property deals with character widths. Here's the relevant code:

// charInfoArray contains (among other things) an attributed character, its origin,
// its size, and info about whether or not it should be displayed

// For each char, the origin and size info were derived from...
let currentCharRect = layoutManager.boundingRect(forGlyphRange: currentCharRange, in: textContainer)

// To display each (attributed) char of "ToT\n" . . .
for (index, charInfo) in charInfoArray.enumerated() {

    guard charInfo.displayed == true else { continue }

    let textView = UITextView()
    textView.backgroundColor = UIColor.clear
    textView.attributedText = charInfo.attrChar
    textView.textContainerInset = UIEdgeInsets.zero

    // let width = charInfo.size!.width
    let width = 30 // arbitrary width

    // Using the automatically generated charInfo.size!.width here
    // appears to make the text view's background opaque!
    textView.frame = CGRect(origin: charInfo.origin!, 
        size: CGSize(width: width, height: charInfo.size!.height))

    textView.frame = textView.frame.offsetBy(dx: 0.0, dy: offsetToCenterY)
    textView.textContainer.lineFragmentPadding = CGFloat(0.0)
    textView.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.2)
    textView.textColor = UIColor.black
    view.addSubview(textView)

    print(charInfo.size!.width)
}

Setting the width to width = charInfo.size!.width seems to make the text view's background opaque! This may be caused by the unusually large width assigned to newline char at the end of the sequence. To eliminate the problem, I'll have to deal with newline chars in another way. In any case, I have no idea why this causes the text view's background to turn opaque, but it does. Setting the width to an arbitrary value of, say, 30 eliminates problem.

Here are the results of using automatically generated and manually set widths, respectively:

The translucent red areas (on yellow backgrounds) show the bounding rectangles for each of the characters, including the newline character.



来源:https://stackoverflow.com/questions/51989787/why-arent-the-backgrounds-within-these-uitextviews-clear

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!