Ios 多行UILabel-高亮显示特定范围并截断以使其可见
我目前正在我的一个应用程序中开发搜索功能,我一直在努力解决一个非常烦人的问题 假设我有以下两段文字: Lorem ipsum dolor sit amet,是一位杰出的献身者。在布朗迪特的康莫多·特里斯蒂克·莱克图斯中。维瓦摩斯·菲利斯·奥迪奥,洛雷姆·埃吉特的拉奥里特,马蒂斯·奥雷姆 尼伯埃利芬德、洛博蒂斯莫里斯a、埃格斯塔斯奥迪奥的杜伊斯 当用户执行搜索时,我将使用表视图显示结果。此表视图中的单元格显示两行文本。为了突出显示匹配的字符,我使用属性文本并设置匹配字符的粗体字体 这一切都很好。但是,我有一个与截断相关的问题。假设用户搜索“egestas odio”。这些单词位于字符串的最末端,因此,很明显,我想显示整个字符串并截断其头部 不幸的是,我无法做到这一点。即使我为Ios 多行UILabel-高亮显示特定范围并截断以使其可见,ios,objective-c,swift,cocoa-touch,uilabel,Ios,Objective C,Swift,Cocoa Touch,Uilabel,我目前正在我的一个应用程序中开发搜索功能,我一直在努力解决一个非常烦人的问题 假设我有以下两段文字: Lorem ipsum dolor sit amet,是一位杰出的献身者。在布朗迪特的康莫多·特里斯蒂克·莱克图斯中。维瓦摩斯·菲利斯·奥迪奥,洛雷姆·埃吉特的拉奥里特,马蒂斯·奥雷姆 尼伯埃利芬德、洛博蒂斯莫里斯a、埃格斯塔斯奥迪奥的杜伊斯 当用户执行搜索时,我将使用表视图显示结果。此表视图中的单元格显示两行文本。为了突出显示匹配的字符,我使用属性文本并设置匹配字符的粗体字体 这一切都很好。但
NSMutableParagraphStyle
设置了正确的截断,我将其添加为属性字符串的属性,但它不起作用。我看到标签的开头是尾巴被截断而不是头部
我发现,如果删除所有换行符,这个问题在某种程度上得到了解决。然而,在我的情况下,这不是很实际
有人知道我如何克服这个障碍吗?或者,你可以给我一些更一般的建议,告诉我如何以稍微不同的方式实现我需要的功能。这似乎相当普遍,而且很可能有一些开源库可以帮助实现这一点。不幸的是,到目前为止我还没有找到
提前谢谢 给定一个字符串和一个您想要保留的范围,这将从任意一条边进入,直到截断的字符串符合给定的大小。您需要做额外的工作来重新计算截断字符串中的范围 Swift 4
func truncatedString(for text: String, with attributes: [NSAttributedStringKey: Any], constrainedTo size: CGSize, keeping range: Range<String.Index>?) -> String {
let nsString = NSString(string: text)
var nsRange = NSMakeRange(nsString.length / 2, 0)
if let range = range {
nsRange = NSRange(range, in: text)
}
var truncatedString = nsString
let elipsis = "..."
let elipsisWidth = elipsis.size(withAttributes: attributes).width
var shouldAddFrontElipsis = false
var shouldAddBackElipsis = false
var constrainedWidthIncludingElipsis = size.width
if nsRange.location > 0 {
shouldAddFrontElipsis = true
constrainedWidthIncludingElipsis -= elipsisWidth
}
if NSMaxRange(nsRange) < nsString.length {
shouldAddBackElipsis = true
constrainedWidthIncludingElipsis -= elipsisWidth
}
var startIndex = 0
var endIndex = nsString.length
while (truncatedString.boundingRect(with: CGSize(width: constrainedWidthIncludingElipsis, height: .greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: attributes, context: nil).size.height > size.height) {
if startIndex == nsRange.location && endIndex == NSMaxRange(nsRange) {
break
} else {
if startIndex < nsRange.location {
startIndex += 1
}
if endIndex > NSMaxRange(nsRange) {
endIndex -= 1
}
truncatedString = NSString(string: nsString.substring(with: NSMakeRange(startIndex, endIndex - startIndex)))
}
}
if startIndex == 0 {
shouldAddFrontElipsis = false
}
if endIndex == nsString.length {
shouldAddBackElipsis = false
}
return (shouldAddFrontElipsis ? elipsis : "") + String(truncatedString) + (shouldAddBackElipsis ? elipsis : "")
}
func truncatedString(对于文本:String,具有属性:[NSAttributedStringKey:Any],约束为大小:CGSize,保留范围:range?->String{
设nsString=nsString(字符串:文本)
var nsRange=NSMakeRange(nsString.length/2,0)
如果let range=range{
nsRange=nsRange(范围,单位:文本)
}
var truncatedString=nsString
让省略“…”
让elipsisWidth=elipsis.size(withAttributes:attributes).width
var shouldAddFrontElipsis=false
var shouldAddBackElipsis=false
var constrainedWidthIncludingElipsis=size.width
如果nsRange.location>0{
shouldAddFrontElipsis=true
约束宽度,包括Elipsis-=elipsisWidth
}
如果NSMaxRange(nsRange)size.height{
如果startIndex==nsRange.location&&endIndex==NSMaxRange(nsRange){
打破
}否则{
如果startIndexNSMaxRange(nsRange){
endIndex-=1
}
truncatedString=NSString(字符串:NSString.substring(带:NSMakeRange(startIndex,endIndex-startIndex)))
}
}
如果startIndex==0{
shouldAddFrontElipsis=false
}
如果endIndex==nsString.length{
shouldAddBackElipsis=false
}
返回(shouldAddFrontElipsis?elipsis:)+字符串(截断字符串)+(shouldAddBackElipsis?elipsis:)
}
给定一个字符串和一个要保留的范围,这将从任意一条边进入,直到截断的字符串符合给定的大小。您需要做额外的工作来重新计算截断字符串中的范围
Swift 4
func truncatedString(for text: String, with attributes: [NSAttributedStringKey: Any], constrainedTo size: CGSize, keeping range: Range<String.Index>?) -> String {
let nsString = NSString(string: text)
var nsRange = NSMakeRange(nsString.length / 2, 0)
if let range = range {
nsRange = NSRange(range, in: text)
}
var truncatedString = nsString
let elipsis = "..."
let elipsisWidth = elipsis.size(withAttributes: attributes).width
var shouldAddFrontElipsis = false
var shouldAddBackElipsis = false
var constrainedWidthIncludingElipsis = size.width
if nsRange.location > 0 {
shouldAddFrontElipsis = true
constrainedWidthIncludingElipsis -= elipsisWidth
}
if NSMaxRange(nsRange) < nsString.length {
shouldAddBackElipsis = true
constrainedWidthIncludingElipsis -= elipsisWidth
}
var startIndex = 0
var endIndex = nsString.length
while (truncatedString.boundingRect(with: CGSize(width: constrainedWidthIncludingElipsis, height: .greatestFiniteMagnitude), options: .usesLineFragmentOrigin, attributes: attributes, context: nil).size.height > size.height) {
if startIndex == nsRange.location && endIndex == NSMaxRange(nsRange) {
break
} else {
if startIndex < nsRange.location {
startIndex += 1
}
if endIndex > NSMaxRange(nsRange) {
endIndex -= 1
}
truncatedString = NSString(string: nsString.substring(with: NSMakeRange(startIndex, endIndex - startIndex)))
}
}
if startIndex == 0 {
shouldAddFrontElipsis = false
}
if endIndex == nsString.length {
shouldAddBackElipsis = false
}
return (shouldAddFrontElipsis ? elipsis : "") + String(truncatedString) + (shouldAddBackElipsis ? elipsis : "")
}
func truncatedString(对于文本:String,具有属性:[NSAttributedStringKey:Any],约束为大小:CGSize,保留范围:range?->String{
设nsString=nsString(字符串:文本)
var nsRange=NSMakeRange(nsString.length/2,0)
如果let range=range{
nsRange=nsRange(范围,单位:文本)
}
var truncatedString=nsString
让省略“…”
让elipsisWidth=elipsis.size(withAttributes:attributes).width
var shouldAddFrontElipsis=false
var shouldAddBackElipsis=false
var constrainedWidthIncludingElipsis=size.width
如果nsRange.location>0{
shouldAddFrontElipsis=true
约束宽度,包括Elipsis-=elipsisWidth
}
如果NSMaxRange(nsRange)size.height{
如果startIndex==nsRange.location&&endIndex==NSMaxRange(nsRange){
打破
}否则{
如果startIndexNSMaxRange(nsRange){
endIndex-=1
}
truncatedString=NSString(字符串:NSString.substring(带:NSMakeRange(startIndex,endIndex-startIndex)))
}
}
如果startIndex==0{
shouldAddFrontElipsis=false
}
如果endIndex==nsString.length{
shouldAddBackElipsis=false
}
返回(shouldAddFr