gpt4 book ai didi

ios - 如何通过点击 UITextView 中的特定字符来显示圆角灰色背景?

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:04:31 29 4
gpt4 key购买 nike

我正在尝试使用 UITextView 显示文本。我在显示长文本时添加了“查看更多”。我想在点击它时更改背景颜色。我设置了NSAttributedString的背景,但是我不能很好地设置圆角和边距。

谢谢!

我想做什么!

当点击添加到 UITextView 的字符时,具有足够边距的灰色背景和圆角。

注意:已经可以点击一个角色了。这个问题是关于点击时的效果。

"See More" example

"Cross lines" example

类似问题

NSAttributedString background color and rounded corners

How to set NSString's background cornerRadius on iOS7

最佳答案

在 UITextView 的文本中添加带圆角的背景颜色。此答案将为您的问题提供一些想法。

逻辑:

UITextView 中,我添加了 UITapGestureRecognizer,它通过 Character 检测用户的点击 Action Character。如果用户点击 subString 中的任何一个 Character,将创建新的 UIView 并触发 Timer。当计时器结束时,创建的 UIView 将从 UITextView 中删除。

myTextView.position的帮助下,我们可以获得subString的CGRect。这是 Created UIView 的框架。 subString中每个单词的Size (WIDTH),可以从SizeAtrributes中获取。

@IBOutlet weak var challengeTextVw: UITextView!
let fullText = "We Love Swift and Swift attributed text "
var myString = NSMutableAttributedString ()
let subString = " Swift attributed text "
var subStringSizesArr = [CGFloat]()
var myRange = NSRange()
var myWholeRange = NSRange()
let fontSize : CGFloat = 25
var timerTxt = Timer()
let delay = 3.0


override func viewDidLoad() {
super.viewDidLoad()

myString = NSMutableAttributedString(string: fullText)
myRange = (fullText as! NSString).range(of: subString)
myWholeRange = (fullText as! NSString).range(of: fullText)
let substringSeperatorArr = subString.components(separatedBy: " ")

print(substringSeperatorArr)
print(substringSeperatorArr.count)
var strConcat = " "

for str in 0..<substringSeperatorArr.count
{

strConcat = strConcat + substringSeperatorArr[str] + " "
let textSize = (strConcat as! NSString).size(withAttributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: fontSize)])
print("strConcatstrConcat ", strConcat)

if str != 0 && str != (substringSeperatorArr.count - 2)
{
print("times")
subStringSizesArr.append(textSize.width)
}

}
let myCustomAttribute = [NSAttributedStringKey.init("MyCustomAttributeName") : "some value", NSAttributedStringKey.foregroundColor : UIColor.orange] as [NSAttributedStringKey : Any]
let fontAtrib = [NSAttributedStringKey.font : UIFont.systemFont(ofSize: fontSize)]
myString.addAttributes(myCustomAttribute, range: myRange)
myString.addAttributes(fontAtrib, range: myWholeRange)

challengeTextVw.attributedText = myString
let tap = UITapGestureRecognizer(target: self, action: #selector(myMethodToHandleTap))
tap.delegate = self

challengeTextVw.addGestureRecognizer(tap)

challengeTextVw.isEditable = false
challengeTextVw.isSelectable = false
}


@objc func myMethodToHandleTap(_ sender: UITapGestureRecognizer) {

let myTextView = sender.view as! UITextView
let layoutManager = myTextView.layoutManager

let numberOfGlyphs = layoutManager.numberOfGlyphs
var numberOfLines = 0
var index = 0
var lineRange:NSRange = NSRange()

while (index < numberOfGlyphs) {

layoutManager.lineFragmentRect(forGlyphAt: index, effectiveRange: &lineRange)
index = NSMaxRange(lineRange);
numberOfLines = numberOfLines + 1

}

print("noLin ", numberOfLines)

// location of tap in myTextView coordinates and taking the inset into account
var location = sender.location(in: myTextView)
location.x -= myTextView.textContainerInset.left;
location.y -= myTextView.textContainerInset.top;

// character index at tap location
let characterIndex = layoutManager.characterIndex(for: location, in: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

// if index is valid then do something.
if characterIndex < myTextView.textStorage.length
{
// print the character index
print("character index: \(characterIndex)")

// print the character at the index
let myRangee = NSRange(location: characterIndex, length: 1)
let substring = (myTextView.attributedText.string as NSString).substring(with: myRangee)
print("character at index: \(substring)")

// check if the tap location has a certain attribute
let attributeName = NSAttributedStringKey.init("MyCustomAttributeName")

let attributeValue = myTextView.attributedText.attribute(attributeName, at: characterIndex, effectiveRange: nil) as? String

if let value = attributeValue
{
print("You tapped on \(attributeName) and the value is: \(value)")
print("\n\n ererereerer")


timerTxt = Timer.scheduledTimer(timeInterval: delay, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)

myTextView.layoutManager.ensureLayout(for: myTextView.textContainer)

// text position of the range.location
let start = myTextView.position(from: myTextView.beginningOfDocument, offset: myRange.location)!
// text position of the end of the range
let end = myTextView.position(from: start, offset: myRange.length)!

// text range of the range
let tRange = myTextView.textRange(from: start, to: end)

// here it is!
let rect = myTextView.firstRect(for: tRange!) //firstRectForRange(tRange)
var secondViewWidthIndex = Int()
for count in 0..<subStringSizesArr.count
{
if rect.width > subStringSizesArr[count]
{
secondViewWidthIndex = count
}
}

let backHideVw = UIView()
backHideVw.frame.origin.x = rect.origin.x
backHideVw.frame.origin.y = rect.origin.y + 1
backHideVw.frame.size.height = rect.height
backHideVw.frame.size.width = rect.width

backHideVw.backgroundColor = UIColor.brown
backHideVw.layer.cornerRadius = 2
backHideVw.tag = 10
myTextView.addSubview(backHideVw)
myTextView.sendSubview(toBack: backHideVw)


if numberOfLines > 1
{
let secondView = UIView()
secondView.frame.origin.x = 0
secondView.frame.origin.y = backHideVw.frame.origin.y + backHideVw.frame.size.height
secondView.frame.size.height = backHideVw.frame.size.height
secondView.frame.size.width = (subStringSizesArr.last! - subStringSizesArr[secondViewWidthIndex]) + 2
secondView.backgroundColor = UIColor.brown
secondView.layer.cornerRadius = 2
secondView.tag = 20
backHideVw.frame.size.width = subStringSizesArr[secondViewWidthIndex]

myTextView.addSubview(secondView)
print("secondView.framesecondView.frame ", secondView.frame)

myTextView.sendSubview(toBack: secondView)
}

print("rectrect ", rect)

}

}

}

@objc func delayedAction()
{

for subVws in challengeTextVw.subviews
{
if (String(describing: subVws).range(of:"UIView") != nil)
{
if (subVws as! UIView).tag == 10 || (subVws as! UIView).tag == 20
{
subVws.removeFromSuperview()
}
}
}

}

通过增加字体大小尝试了所有尝试。

尝试 1

enter image description here

尝试 2

enter image description here

尝试 3

enter image description here

关于ios - 如何通过点击 UITextView 中的特定字符来显示圆角灰色背景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48877118/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com