Эта проблема возникла в связи с проблемой, с которой я столкнулся вчера , для которой я должен быть в состоянии найти обходной путь. В ходе дальнейших исследований я обнаружил, что это происходит шире, чем я первоначально думал. Ранее я заметил это только в отображаемом тексте, который содержал хотя бы один символ новой строки, но ниже это не так.
Проблема, по-видимому, является результатом использования метода boundingRect NSLayoutManager для получения (среди прочего) отдельных значений ширины символов, а затем использования этих значений для установки свойств ширины кадра UITextView символов. Это, очевидно, приводит к игнорированию установки backgroundColor текстового представления в UIColor.clear (то есть фон становится непрозрачным). Приведенный ниже код игровой площадки воспроизводит проблему, показанную красным текстом , и показывает обходной путь использования константы для ширины в черном . Чем плотнее кернинг, тем сильнее выражен эффект.
Это ошибка? Или это причуды из-за чего-то еще?
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.bounds = CGRect(x: -100, y: -100, width: 200, height: 200)
view.backgroundColor = .white
let str = "..T.V.W.Y.."
let strStorage = NSTextStorage(string: str)
let layoutManager = NSLayoutManager()
strStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size: view.bounds.size)
textContainer.lineFragmentPadding = 0.0
layoutManager.addTextContainer(textContainer)
let strArray = Array(str)
struct CharInfo {
var char: Character
var origin: CGPoint?
var size: CGSize?
}
var charInfoArray = [CharInfo]()
for index in 0..<str.count {
charInfoArray.append(CharInfo.init(char: strArray[index], origin: nil, size: nil))
let charRange = NSMakeRange(index, 1)
let charRect = layoutManager.boundingRect(forGlyphRange: charRange, in: textContainer)
charInfoArray[index].origin = charRect.origin
charInfoArray[index].size = charRect.size
}
for charInfo in charInfoArray {
let textView0 = UITextView()
textView0.backgroundColor = UIColor.clear // Ignored in this case!!
textView0.text = String(charInfo.char)
textView0.textContainerInset = UIEdgeInsets.zero
let size0 = charInfo.size!
textView0.frame = CGRect(origin: charInfo.origin!, size: size0)
textView0.textContainer.lineFragmentPadding = CGFloat(0.0)
textView0.textColor = UIColor.red
view.addSubview(textView0)
let textView1 = UITextView()
textView1.backgroundColor = UIColor.clear // Required
textView1.text = String(charInfo.char)
textView1.textContainerInset = UIEdgeInsets.zero
var size1 = charInfo.size!
size1.width = 20 // But changing .height has no effect on opacity
textView1.frame = CGRect(origin: charInfo.origin!, size: size1)
textView1.frame = textView1.frame.offsetBy(dx: 0, dy: 20)
textView1.textContainer.lineFragmentPadding = CGFloat(0.0)
textView1.textColor = UIColor.black
view.addSubview(textView1)
}
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()