SelectableTextView 1.0.3

SelectableTextView 1.0.3

测试已测试
语言 SwiftSwift
许可证 MIT
发布最后发布2017年11月
SwiftSwift 版本4.0
SPM支持 SPM

Jeff Hurray 维护。



问题

UILabelUITextView 在文本选择方面的支持令人不满意。

现有的解决方案,如 TTTAttributedLabel 很棒,但提供的文本选择 API 相对有限。

特性

安装

手动添加到项目

从仓库中克隆并手动添加 /SelectableTextView 目录中的文件

用法

import SelectableTextView

let textView = SelectableTextView()
textView.text = "Hello World!"
textView.truncationMode = .truncateTail
textView.alignment = .center
textView.numberOfLines = 1

let greetingValidator = MatchesTextValidator(text: "hello")
textView.registerValidator(_ validator: greetingValidator) { (validText, validator) in
	// Handle selection of "Hello"
}

let exclamationValidator = SuffixValidator(suffix: "!")
textView.registerValidator(_ validator: exclamationValidator) { (validText, validator) in
	// Handle selection of "World!"
}

文本选择

要创建可选文本,您需要创建并注册一个验证器。验证器必须遵守 TextSelectionValidator 协议。

let hashtagValidator = PrefixValidator(prefix: "#")
textView.registerValidator(validator: hashtagValidator) { (validText, validator) in
	// Handle selection of hashtag
}

您可以在任何时候注销验证器。

textView.removeValidator(validator: hashtagValidator)

自定义验证器

这里有关于如何使用 TextSelectionValidator 协议 创建自定义验证器 的资源。

还有其他一些更具体的协议,使得自定义更容易,例如 ContainerTextSelectionValidatorCompositeTextSelectionValidator

预写验证器

提供了一些预写验证器。这些可以作为现有的,作为构建更复杂验证器的积木,以及作为如何构建自定义验证器的示例。

文本验证器
MatchesTextValidator(text: String, caseSensitive: Bool = false)

ContainsTextValidator(text: String, caseSensitive: Bool = false)

PrefixValidator(text: String, caseSensitive: Bool = false)

SuffixValidator(text: String, caseSensitive: Bool = false)

HashtagTextValidator()

AtSymbolTagTextValidator()

QuotationsTextValidator()

HandlebarsValidator(searchableText: String, replacementText: String)
抽象验证器
ReverseValidator(validator: TextSelectionValidator)

ContainerValidator(validator: TextSelectionValidator, selectionAttributes: [String: Any]? = nil)

CompositeValidator(validators: [TextSelectionValidator], selectionAttributes: [String: Any]? = nil)
链接验证器
LinkValidator() // Validates any link (HTTP, HTTPS, file, etc...)

HTTPLinkValidator() // Validates HTTP and HTTPS links

UnsafeLinkValidator() // Validates HTTP links

HTTPSLinkValidator()

CustomLinkValidator(urlString: String!, replacementText: String? = nil) 

可以使用 LinkValidatorAttributes 协议进行自定义。示例 在此

正则表达式验证器
RegexValidator(pattern: String, options: NSRegularExpression.Options = .caseInsensitive)

EmailValidator()

PhoneNumberValidator()

文本扩展

您可以使用以下方法添加文本扩展按钮


public func addExpansionButton(collapsedState: (text: String, lines: Int), expandedState: (text: String, lines: Int), attributes: [String: Any]? = nil)

您可以使用以下方法删除扩展按钮

public func removeExpansionButton(numberOfLines: Int = 1)

示例

let attributes = [NSForegroundColorAttributeName: purple]
textView.addExpansionButton(collapsedState: ("More...", 2),
                             expandedState: ("Less", 0),
                                attributes: attributes)
                                
...

textView.removeExpansionButton(numberOfLines: 2)

您可以使用 SelectedBackgroundColorAttribute 属性和 HighlightedTextSelectionAttributes 结构作为属性键来自定义扩展按钮的背景颜色。

let attributes: [String: Any] = [HighlightedTextSelectionAttributes.SelectedBackgroundColorAttribute : UIColor.purple]

自定义

text

  • 设置文本视图的内容
  • 类型: String?

font

  • 设置文本视图的字体
  • 类型: UIFont
  • 默认: UIFont.systemFont(ofSize: 17)

textColor

  • 设置默认的文本颜色
  • 类型: UIColor
  • 默认: UIColor.darkText

attributedText

  • 使用有属性文本覆盖 texttextColor
  • 类型: NSAttributedString?
  • 默认: nil

textAlignment

  • 设置文本视图中文本的对齐方式
  • 类型: TextAlignment
  • 支持 3 种类型: .left.right.center
  • 默认: .left

lineBreakMode

  • 确定文本视图如何处理新行
  • 类型:LineBreakMode
  • 支持 1 种类型:.wordWrap
    • 默认:. wordWrap
  • 参见 目标

truncationMode

  • 确定文本视图最后一行的最后一个单词的行为
  • 类型:TruncationMode
  • 支持 2 种类型:.clipping.truncateTail
  • 默认:.clipping
  • 参见 目标

numberOfLines

  • 确定文本视图中的行数
  • 类型:Int
  • 默认:0
  • 0 行表示无限制,类似于 UILabel

lineSpacing

  • 确定行与行之间的间距
  • 类型:CGFloat
  • 默认:0
  • 支持负值

textContainerInsets

  • 设置文本视图的内容内边距
  • 类型:UIEdgeInsets
  • 默认:UIEdgeInsets.zero

selectionAttributes

  • 设置可选取文本的默认选取属性
  • 类型:[String : AnyObject]?
  • 默认:color = tintColorfont = boldSystemFont(ofSize: font.pointSize + 2)

isExpanded

  • 跟踪展开按钮的状态
  • 类型:Bool?
  • 默认:nil。只有当展开按钮被添加时才会返回值
  • 如果展开按钮被添加,此属性将切换状态

textContentSize

  • 只读,返回文本内容的大小
  • 类型:CGSize

isSelectionEnabled

  • 确定是否为文本视图启用选取
  • 类型:Bool
  • 默认:true

isScrollEnabled

  • 确定是否为文本视图启用滚动
  • 类型:Bool
  • 默认:false

scrollDelegate

  • 将文本视图的滚动事件转发
  • 类型:SelectableTextViewDelegate?

delegate

  • 代表为文本视图
  • 类型:SelectableTextViewScrollDelegate?

支持的转义字符

  • 换行 \n
  • 制表符 \t
  • 空字符终结符 \0

如果您想在可选文本旁边放入文本,但仍需正确验证文本,请使用空字符终结符。

let text = "The period next to the #Hashtag\0. Will not be highlighted if I use a hashtag validator."

杂项

framesOfWordsMatchingValidator

您可以使用以下方法获取文本视图内单词的相对框架。这就是我在第一个示例 Gif 中设置星星效果的方法。

public func framesOfWordsMatchingValidator(_ validator: TextSelectionValidator) -> [CGRect]
制表符长度

您可以使用 TabTextModelConfig.numberOfSpaces 调整制表符字符产生的空格数。默认值是 4。

TabTextModelConfig.numberOfSpaces = 2

界面构建器

您可以通过界面构建器设置大多数自定义属性。《SelectableTextView》标记为@IBDesignable

  • numberOfLines: Int
  • text: String
  • textColor: UIColor
  • lineSpacing: Float
  • isSelectionEnabled: Bool
  • isScrollEnabled: Bool
  • fontSize: Float
  • truncateTail: Bool
  • topTextInsets: Float
  • bottomTextInsets: Float
  • leftTextInsets: Float
  • rightTextInsets: Float

Delegate

为所有的 SelectableTextViewDelegate 方法提供了默认实现。

public protocol SelectableTextViewDelegate: class {
    
    /// Resolves conflict between multiple validates that return `true` from their `validate:` method
    //
    // i.e. PrefixTextValidator for `#` and `#my` will both return true for `#myCoolHashtag`,
    // but the actions they are registered for may differ
    //
    /// Default behavior is to choose the first validator in the composite validator's `validators` array
    func resolveValidationConflictsForSelectableTextView(textView: SelectableTextView, conflictingValidators: [TextSelectionValidator]) -> TextSelectionValidator
    
    /// Defaults to `false`
    func animateExpansionButtonForSelectableTextView(textView: SelectableTextView) -> Bool
    
    /// Defaults to `.truncateTail`
    func truncationModeForWordsThatDontFitForSelectableTextView(textView: SelectableTextView) -> TruncationMode
    
    /// Optional, Default empty implementation provideed
    func selectableTextViewContentHeightDidChange(textView: SelectableTextView, oldHeight: CGFloat, newHeight: CGFloat)
}

滚动

SelectableTextView 支持滚动,并通过 SelectableTextViewScrollDelegate 转发滚动事件。

public protocol SelectableTextViewScrollDelegate: class {
    
    func selectableTextViewDidScroll(_ scrollView: UIScrollView)
    func selectableTextViewWillBeginDragging(_ scrollView: UIScrollView)
    func selectableTextViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
    func selectableTextViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
    func selectableTextViewWillBeginDecelerating(_ scrollView: UIScrollView)
    func selectableTextViewDidEndDecelerating(_ scrollView: UIScrollView)
    func selectableTextViewDidEndScrollingAnimation(_ scrollView: UIScrollView)
}

您也可以滚动到特定的单词或第一个通过验证器的单词。

/// Scrolls to the first instance of the word
/// Attempts to match the text and display text of a word
public func scrollToWord(_ word: String, position: ScrollPosition, animated: Bool)
    
   /// Scrolls to the first instance of a word that passes the provided TextSelectionValidator
public func scrollToWordPassingValidator(_ validator: TextSelectionValidator, position: ScrollPosition, animated: Bool)

目标

  • 字符换行
  • 更多截断样式:.head.center

联系方式 && 贡献

请随时发送电子邮件至 [email protected]。我很乐意听听您的想法,或者看看已经使用了此功能的示例。

MIT 许可证