ios – 使用文本包将UITextView插入UITextField?

我正在使用一个 text view替换占位符与UITextFields.我传递一个包含占位符标记的多个实例的文本的对象(一个结构体或一个字典).该字典还包含一组我们要从中收集数据的字段.我的目标是在我的文本中放置UITextField(或其他视图),并隐藏令牌.

使用NSLayoutManager方法来计算文本容器中占位符标记的位置,我将这些点转换为CGRects,然后将排除路径转换为文本字段周围的文本.这就是这样的:

func createAndAssignExclusionPathsForInputTextFields () {

    var index = 0
    let textFieldCount = self.textFields.count

    var exclusionPaths : [UIBezierPath] = []

    while index < textFieldCount {

        let textField : AgreementTextField = self.textFields[index]

        let location = self.calculatePositionOfPlaceholderAtIndex(index)
        let size = textField.intrinsicContentSize()
        textField.frame = CGRectMake(location.x,location.y,size.width,size.height)

        exclusionPaths.append(textField.exclusionPath())

        index = index + 1
    }

    self.textContainer.exclusionPaths = exclusionPaths
}

// …

func calculatePositionOfPlaceholderAtIndex(textIndex : NSInteger) -> CGPoint {

    let layoutManager : NSLayoutManager = self.textContainer.layoutManager!

    let delimiterRange = self.indices[textIndex]
    let characterIndex = delimiterRange.location
    let glyphRange = self.layoutManager.glyphRangeForCharacterRange(delimiterRange,actualCharacterRange:nil)
    let glyphIndex = glyphRange.location
    let rect = layoutManager.lineFragmentRectForGlyphAtIndex(glyphIndex,effectiveRange: nil,withoutAdditionalLayout: true)

    let remainingRect : UnsafeMutablePointer<CGRect> = nil

    let textContainerRect = self.textContainer.lineFragmentRectForProposedRect(rect,atIndex: characterIndex,writingDirection: .LeftToRight,remainingRect: remainingRect)

    let position = CGPointMake(textContainerRect.origin.x,textContainerRect.origin.y)

    return position
}

在这一点上,我有三个问题:

>一旦我将一个排除路径分配给了textContainer,其他占位符的计算字形位置现在都是错误的.
> calculatePositionOfPlaceholderAtIndex方法给我很好的y值,但是x值都是0.
>我还没有成功地隐藏占位符令牌.

所以,为了解决我的列表中的第一个问题,我尝试添加排除路径,然后再计算下一个,通过更改createAndAssignExclusionPathsForInputTextFields:

func createAndAssignExclusionPathsForInputTextFields () {

    var index = 0
    let textFieldCount = self.textFields.count

    while index < textFieldCount {

        let textField : AgreementTextField = self.textFields[index]

        let location = self.calculatePositionOfPlaceholderAtIndex(index)
        let size = textField.intrinsicContentSize()
        textField.frame = CGRectMake(location.x,size.height)

        self.textContainer.exclusionPaths.append(textField.exclusionPath())

        index = index + 1
    }
}

现在,我的计算头寸全都返回0,0不是我们想要的.添加排除路径可以理解,使计算的位置无效,但为每个rect方法获得0,0没有帮助.

添加排除路径或隐藏字形后,如何让布局管理器重新计算屏幕上字形的位置?

编辑:每阿兰T答案,我没有运气尝试以下:

func createAndAssignExclusionPathsForInputTextFields () {

    var index = 0
    let textFieldCount = self.textFields.count

    var exclusionPaths : [UIBezierPath] = []

    while index < textFieldCount {

        let textField : AgreementTextField = self.textFields[index]

        let location = self.calculatePositionOfPlaceholderAtIndex(index)
        let size = textField.intrinsicContentSize()
        textField.frame = CGRectMake(location.x,size.height)

        exclusionPaths.append(textField.exclusionPath())
        self.textContainer.exclusionPaths = exclusionPaths

        self.layoutManager.ensureLayoutForTextContainer(self.textContainer)
        index = index + 1
    }

    self.textContainer.exclusionPaths = exclusionPaths
}

解决方法

我只能提出我自己在TextKit上的新意见,但是在你的代码中瞪着我的东西,我以为我会提到它,以防它有帮助.

在你的createAndAssignExclusionPathsForInputTextFields函数中,你按照你的self.textFields数组的顺序处理你的字段.

当您在函数末尾设置self.textContainer.exclusionPaths的值时,布局管理器将(可能)重新流动所有排除的文本,从而使您的一些计算无效,而不考虑其他的影响排除.

这样做的方法是排序你的self.textFields数组,使它们对应于文本流(他们可能已经按照这个顺序,我不能告诉).然后,您必须清除self.textContainer.exclusionPath中的所有排除项,并将它们逐一添加,以便在计算下一个排除之前,布局管理器将围绕以前添加的排除的文本重新排列. (我相信它每次设置排除次数都是这样,但如果没有,则可能需要调用layoutManager的ensureLayoutForManager函数)

您必须以文本流顺序执行此操作,以便将每个排除添加到文本区域,这些区域不会使任何先前的排除项无效.

优化这一点,以避免完全清除/重建排除也是可能的,但我建议在尝试之前达到工作基线.

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...