optonaut / ActiveLabel.swift

UILabel drop-in replacement supporting Hashtags (#), Mentions (@) and URLs (http://) written in Swift
MIT License
4.47k stars 686 forks source link

Incorrect selected rect #126

Closed cruisediary closed 5 years ago

cruisediary commented 7 years ago

I love this framework

but unfortunately i found somthing like bug

this is simple project

environment

just set hashtag normal and selected color , mentiontag normal and selected color

and set text to "#1234\n#1234\n#5678\n@asdf\n\n\n#asdfa\n#asdfasdf\n\n"

screen shot 2016-10-21 at 4 27 26 pm screen shot 2016-10-21 at 4 24 29 pm screen shot 2016-10-21 at 4 25 10 pm

problem is before tag selected when i touch empty rect

is this duplicated problem, how can i fix it :)

polqf commented 7 years ago

This is a known problem, but haven't find a solution for it

cruisediary commented 7 years ago

How about adding pattern like '\s' to solve this problem that pattern cause event but do nothing, not changing selected color and hash, mention, url patterns should not affected same to complementary set if someone use custom pattern comprising '\t,\n~' doesn't help this

but this patterns can't solve last sentense cause this problem, must be adjusted if last sentence of activeLabel fully filled the labels's empty rect then doesn't need to add space char but if can add space and doesn't change label's height, add space to match above pattern

  1. Add '\s' patterns to delegate empty rect selected event without selectedColor
  2. If last sentence is too short fill empty rect then add space char to match '\s' patterns

Is this way can solve this problem and moreover attributedText problem?

polqf commented 7 years ago

Hi @cruisediary I don't quite get your workaround.

If you think that you have a good solution, I would be really have to receive a PR

JordanMcCulloch commented 7 years ago

The issue is due to setting the index with layoutManager.glyphIndex in the ActiveLabel.swift element(at location: CGPoint) method.

As per the docs:

If no glyph is under point, the nearest glyph is returned.

Therefore when you tap in the whitespace, it actually grabs the nearest glyph and uses that location. Hence why you need to replace your current if index is in element check in element(at location: CGPoint) with the following:

let elementRect = layoutManager.boundingRect(forGlyphRange: element.range, in: textContainer)
if elementRect.contains(correctLocation){
    return element
}
stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.